繁体   English   中英

为什么这个简单的代码会导致我的应用程序冻结?

[英]Why is this simple code causing my app to freeze?

我的应用程序一直无缘无故地冻结,所以我简化了代码,直到解决了问题。 显然有两个同步锁(一个在简单的 sub 中,另一个在计时器中)导致了它。 这是简化的代码:

    String var1 = "";
    String var2 = "";
    private void button1_Click(object sender, EventArgs e)
    {
        Thread thread = new Thread(test_sub);
        thread.Start();
    }
    private void test_sub()
    {
        lock (var1)
        {
            Thread.Sleep(1000000);
        }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        lock (var2){}
    }

定时器 1 默认启用,滴答之间有 1 秒的延迟。 按下 button1 后,UI 立即冻结。 谁能解释一下导致这种奇怪行为的原因以及可以做些什么? 谢谢!

您的问题不在于线程,也不在于锁本身。 问题在于用于锁定的对象:两个锁都锁定在空字符串上,该字符串已优化为使用String.Empty实例。

所以你的代码如下:

private void button1_Click(object sender, EventArgs e)
{
    Thread thread = new Thread(test_sub);
    thread.Start();
}
private void test_sub()
{
    lock (String.Empty)
    {
        Thread.Sleep(1000000);
    }
}

private void timer1_Tick(object sender, EventArgs e)
{
    lock (String.Empty){}
}

一旦输入 timer1_Tick 就会锁定 UI 线程,因为计时器(在 UI 线程上运行)将锁定与 test_sub 相同的test_sub实例(在单独的线程上运行)。

为了确保使用两个锁,你应该像这样声明你的锁对象:

private readonly object _lock1 = new object();
private readonly object _lock2 = new object();

这保证了相同对象上不会发生外部锁定,并且两个锁定对象是不同的实例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM