C#线程安全代码

时间:2015-04-24 14:30:48

标签: c# multithreading

此代码线程是否安全?

使用Task在新线程中调用

DoStuff

Task.Factory.StartNew(() => DoStuff());


private void DoStuff()
{
    List<SalesRecord> salesRecords = new List<SalesRecord>();
    SalesRecord salesRecord1 = new SalesRecord {Amount = 10.0, Sales = 1};
    SalesRecord salesRecord2 = new SalesRecord {Amount = 15.0, Sales = 1};
    SalesRecord salesRecord3 = new SalesRecord {Amount = 1.0, Sales = 2};
    salesRecords.Add(salesRecord1);
    salesRecords.Add(salesRecord2);
    salesRecords.Add(salesRecord3);
    SalesRecord result = Util.SumSales(salesRecords);
}

仅用于存储数据的结构:

public struct SalesRecord
{
    public uint Sales;
    public double Amount;
}

东西

public static class Util
{
    public static SalesRecord SumSales(List<SalesRecord> records)
    {
        SalesRecord result = new SalesRecord();

        result.Amount = records.FindAll(record => (record.Sales == 1)).Sum(record => record.Amount);
        result.Sales = 1;
        return result;
    }
}

3 个答案:

答案 0 :(得分:9)

  

此代码线程是否安全?

是的,确实如此。此代码不使用任何共享状态。根据定义,不使用任何共享状态的代码是线程安全的。

您可以在任意数量的线程中同时调用DoStuff而不会出现任何问题。也就是说,DoStuff方法虽然不是很有用。

答案 1 :(得分:4)

您的代码看起来很好。即使DoStuff是通过Task启动的,我也没有在代码中看到您处理类变量的任何地方,它们都是局部变量。

参考: C# : What if a static method is called from multiple threads?

答案 2 :(得分:0)

发布给那些试图弄清楚为什么它的线程安全,即使使用静态方法

在这种特殊情况下,访问Util.SumSales(salesRecords)是线程安全的,因为它是一个线程本地方法(调用此方法的线程将其自己的数据副本提供给方法和数据该线程中的访问权限是调用它的线程所独有的。

当您拨打以下代码时:

Task.Factory.StartNew(() => DoStuff());

您指定一个新线程来处理DoStuff()。在DoStuff中发生的一切(除非你引入可以在其外部操作的变量)都是该新线程所独有的。

我假设您将从DoStuff()中获得更多内容。在这种情况下,您应该将结果存储在Concurrent Collections