Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 线程安全问题_C#_.net_Multithreading_Thread Safety - Fatal编程技术网

C# 线程安全问题

C# 线程安全问题,c#,.net,multithreading,thread-safety,C#,.net,Multithreading,Thread Safety,我知道我们需要注意类内静态成员变量的线程安全。我们需要担心实例成员变量吗?是的,您应该关心,因为同一个类实例方法可以作为回调传递给多个线程。例如: var instance = new Foo(); ThreadPool.QueueUserWorkItem(instance.SomeInstanceMethod); ThreadPool.QueueUserWorkItem(instance.SomeInstanceMethod); 实例方法现在需要同步,因为在这种情况下,共享状态是实例本身。这

我知道我们需要注意类内静态成员变量的线程安全。我们需要担心实例成员变量吗?

是的,您应该关心,因为同一个类实例方法可以作为回调传递给多个线程。例如:

var instance = new Foo();
ThreadPool.QueueUserWorkItem(instance.SomeInstanceMethod);
ThreadPool.QueueUserWorkItem(instance.SomeInstanceMethod);

实例方法现在需要同步,因为在这种情况下,共享状态是实例本身。

这取决于您是否希望您的类型是线程安全的。。。你的意思是什么

大多数情况下,我认为记录该类型不是线程安全的是完全合理的,但是可以通过适当的同步从不同的线程安全地使用。大多数.NET类型都属于这一类

这通常可以确保只有“协调”对象才需要担心同步问题,而不是在每个方法和属性中都加上锁——这是一种痛苦的策略,并且不能真正解决您可能遇到的更广泛的同步问题

当然,自然会从多个线程使用的类型(专门设计用于支持并发的类型,或服务定位器等)应该是线程安全的,并记录在案。同样,完全不可变的类型一开始自然是线程安全的


最后,有一个问题是什么算是“线程安全”开始。你应该阅读这件事,以澄清你应该思考和记录什么样的事情

考虑以下代码:

public void Execute()
{
    Task.Factory.StartNew(Iterrate);
    Task.Factory.StartNew(Add);
}

private List<int> _list = Enumerable.Range(1, 10).ToList();

private void Iterrate()
{
    foreach (var item in _list)
    {
        Console.WriteLine(item);
    }
}

private void Add()
{
    _list.Add(_list.Count);
}

+1详细说明您可以选择并记录类型不是线程安全的。通常,当类型一起使用时,仅仅一个类型是线程安全的是不够的,因为跨多个类型访问的操作需要同步。这就是您需要协调类型处理所有参与类型的线程安全性的地方。@chibacity:没错。你可以花费大量的时间和精力来获得安全的外观,但实际上却没有得到任何好处(并且最终得到了一个更难推理的代码库)。很好的代码示例,给后代多一点解释就好了;)不是每个人都知道这个经典的多线程问题场景中的问题。@chibacity:我相信代码片段值千言万语。此外,我没有时间提供额外的信息:)同意-我非常理解代码,但不是每个人都意识到其中的含义-这毕竟是最初的问题。我这样说是因为我想把你的答案投得更高。方法名称应该以大写字母C#开头吗?很高兴知道。谢谢起初,我没有看到C#标记,而是在考虑Java命名约定。
InvalidOperationException: Collection was modified; enumeration operation may not execute.