如何处理多线程中的竞争条件?

Rya*_*hel 5 c# multithreading race-condition

这是一个例子:

if (control.InvokeRequired)
{
    control.BeginInvoke(action, control);
}
else
{
    action(control);
}
Run Code Online (Sandbox Code Playgroud)

例如,如果在条件和BeginInvoke调用之间调用控件,该怎么办?

另一个与事件有关的例子:

var handler = MyEvent;

if (handler != null)
{
    handler.BeginInvoke(null, EventArgs.Empty, null, null);
}
Run Code Online (Sandbox Code Playgroud)

如果MyEvent在第一行和if语句之间取消订阅,则仍将执行if语句.但是,这是正确的设计吗?如果使用取消订阅也会破坏正确调用事件所需的状态?这个解决方案不仅具有更多代码行(样板文件),而且它不直观,并且可能导致客户端出现意外结果.

怎么说你呢?

Jef*_*tin 5

在我看来,如果这是一个问题,你的线程管理和对象生命周期管理都是鲁莽的,需要重新检查.

在第一个例子中,代码不对称:BeginInvoke不会等待action完成,而是直接调用; 这可能已经是个bug了.

如果你期望另一个线程可能处理你正在使用的控件,你别无选择,只能抓住ObjectDisposedException- 并且它可能不会被抛出,直到你已经在里面action,并且可能不在当前线程上由于BeginInvoke.

假设一旦您取消订阅活动,您将不再收到通知,这是不恰当的.它甚至不需要多个线程来实现 - 只有多个订户.如果第一订户在处理导致第二订户取消订阅的通知时做某事,则当前"在飞行中"的通知仍将转到第二订户.您可以使用事件处理程序例程顶部的guard子句来缓解此问题,但您无法阻止它发生.