c# – ‘死锁’只有一个被锁定的对象?

我在C#中遇到多线程问题.
我使用一个事件来更新另一个线程的表单中的标签,当然我需要使用Invoke()命令.
那部分也很好.
但是,用户可以关闭表单,如果在不幸的时间发送事件,程序可能会崩溃.

所以,我想我会简单地覆盖窗体的Dispose()方法,在锁定代码中将布尔值设置为true,并检查布尔值并在锁定代码调用事件.

但是,每次关闭表单时程序都会完全冻结.

以下是代码中提到的部分:

private object dispose_lock = new object();
private bool _disposed = false;

private void update(object sender,EventArgs e)
{
    if (Invokerequired)
    {
        EventHandler handler = new EventHandler(update);
        lock (dispose_lock)
        {
            if (_disposed) return;
            Invoke(handler); // this is where it crashes without using the lock
        }
        return;
    }

    label.Text = "blah";
}

protected override void Dispose(bool disposing)
{
    eventfullObject.OnUpdate -= update;
    lock (dispose_lock) // this is where it seems to freeze
    {
       _disposed = true; // this is never called
    }
    base.Dispose(disposing);
}

我希望这里的任何人都知道这段代码有什么问题.
先感谢您!

解决方法

我真的很简单.而不是实现棘手的线程安全代码,我只是捕获异常,如果失败则什么都不做.

假设它是ObjectDisposedException:

try
{
    this.Invoke(Invoke(handler));
}
catch (ObjectDisposedException)
{
    // Won't do anything here as
    // the object is not in the good state (diposed when closed)
    // so we can't invoke.
}

它更简单,更直接.如果注释指定了捕获异常的原因,我认为没关系.

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString("x2"));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable<Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include "WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...