c#事件锁定

本文关键字:锁定 事件 | 更新日期: 2023-09-27 17:48:58

c#中是否有一个类似于lock{}的结构,但在事件处理程序中调用时有效,即等待代码块在处理后续事件之前完成

我遇到的问题是锁{}只阻止其他线程获得对象上的锁,但是如果调用同一线程上的事件处理程序,锁块内代码的执行被中断,并且在返回到原始代码的执行之前处理新事件。

object DoStuffLock = new object();
public void DoStuff()
{
    lock (DoStuffLock)
    {
         // Do stuff that we don't want to be interrupted,
         // but because it is called from an event handler 
         // it still can be interrupted despite the lock
    }
}

我目前正在解决这样的问题(但它几乎是不理想的):

object DoStuffLock = new object();
// this gets called from an event, and therefore can be interrupted, 
// locking does not help, so launch separate thread
public void DoStuff()
{
    var x = new Thread(DoStuffInternal);
    x.Start();
}
private void DoStuffInternal()
{
    lock (DoStuffLock)
    {
         // Do stuff that we don't want to be interrupted
    }
}

c#事件锁定

我遇到的问题是锁{}只阻止其他线程获得对象上的锁,但如果同一线程上的事件处理程序被称为

这不可能发生。如果你的线程正在执行,一个事件不能在同一个线程上发生——它必须在另一个线程上引发。

话虽如此,你的"第二种方法"无论如何在许多方面都是优越的。这里有一个隐含的假设,即事件处理程序将很快返回。"阻塞"事件处理程序通常是糟糕设计的标志,并且可能会导致问题,特别是在事件发布者不希望事件阻塞的情况下。

考虑锁定代码,而不是对象。

使用相同的锁对象来锁定不能同时输入的代码片段。

此外,锁并不能阻止中断,它们只是阻止两个线程同时访问同一段代码。

UI事件都是从同一个线程调用的。锁的设计是为了防止多线程。锁是专门为允许同一个线程多次调用同一个锁而设计的,否则会发生死锁。

我认为你的第二个解决方案是正确的。如果你有一段代码必须在一个块中执行,那么你可以在一个新线程中执行。

在像Windows这样的操作系统中,你不能对事件处理的顺序做任何假设。这只能在实时操作系统上完成。

在这种情况下,你可以做的是增加线程优先级。这应该给线程更多的时间(相对于其他线程)。关于。net中线程优先级的更多信息可以在这里找到:http://msdn.microsoft.com/en-us/library/system.threading.threadpriority.aspx