是C#代表线程安全的? [英] Are C# delegates thread-safe?

查看:121
本文介绍了是C#代表线程安全的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果你有一个代表成员变量和多线程一个类实例调用该委托(假设它指向一个长期运行的方法),没有任何竞争问题?

If you have a class instance with a delegate member variable and multiple threads invoke that delegate (assume it points to a long-running method), is there any contention issues?

你需要周围的委托锁定或者是安全的每个线程调用的方法委托点,因为每个线程都有它自己的调用堆栈?

Do you need to lock around the delegate or is it safe for each thread to call the method the delegate points to, since each thread gets it's own call stack?

推荐答案

关于委托的答案是肯定的调用。

调用一个代表是线程安全的,因为代表是不可改变的。但是,你必须确保委托第一存在。该检查可能需要一些同步机制取决于所需的安全水平。

Invoking a delegate is thread-safe because delegates are immutable. However, you must make sure that a delegate exists first. This check may require some synchronization mechanisms depending on the level of safety desired.

例如,下面的可以抛出一个的NullReferenceException 如果 SomeDelegate 是由空检查和调用的另一个线程设置为null。

For example, the following could throw a NullReferenceException if SomeDelegate were set to null by another thread between the null check and the invocation.

if (SomeDelegate != null)
{    
  SomeDelegate();
}



下面是一个小更安全。在这里,我们利用一个事实,即代表是不可改变的。即使另一个线程修改 SomeDelegate 代码harded防止讨厌的的NullReferenceException

The following is a little more safe. Here we are exploiting the fact that delegates are immutable. Even if another thread modifies SomeDelegate the code is harded to prevent that pesky NullReferenceException.

Action local = SomeDelegate;
if (local != null)
{
  local();
}



不过,这可能会导致从未被当<$ C $执行委托C> SomeDelegate 被分配在另一个线程一个非空值。这与一个微妙的内存屏障问题做。 ,以下是最安全的方法

However, this might result in the delegate never being executed if SomeDelegate was assigned a non-null value in another thread. This has to do with a subtle memory barrier problem. The following is the safest method.

Action local = Interlocked.CompareExchange(ref SomeDelegate, null, null);
if (local != null)
{
  local();  
}



关于委托所引用的方法的执行,答案是没有。

您将通过使用同步机制来提供自己的线程安全guarentees。这是因为CLR不会自动为代表的执行提供线程安全guarentees。它可能是,该方法不需要任何进一步的同步,使之安全,特别是如果它从未访问共享状态的情况下。但是,如果方法读取或从共享变量写,那么你将不得不考虑如何防范来自多个线程的并发访问。

You will have to provide your own thread-safety guarentees via the use of synchronization mechanisms. This is because the CLR does not automatically provide thread-safety guarentees for the execution of delegates. It might be the case that the method does not require any further synchronization to make it safe especially if it never access shared state. However, if the method reads or writes from a shared variable then you will have to consider how to guard against concurrent access from multiple threads.

这篇关于是C#代表线程安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆