C# 情况:单独的线程计时器调用UIThread和lock,因为窗体计时器锁对象

C# 情况:单独的线程计时器调用UIThread和lock,因为窗体计时器锁对象,c#,multithreading,C#,Multithreading,情况如下:线程计时器(来自System.Threading.timer)以一定的间隔运行,并使用对象锁定和执行某些操作。UI计时器(System.Windows.Forms.timer)也会按时间间隔和使用相同的对象来考虑窗体。所以他也锁定了这个物体 有时线程计时器会调用UIThread,如下所示: lock (_lockobj) { form.Invoke(new MethodInvoker(delegate { // Do somethings on form })); }

情况如下:线程计时器(来自System.Threading.timer)以一定的间隔运行,并使用对象锁定和执行某些操作。UI计时器(System.Windows.Forms.timer)也会按时间间隔和使用相同的对象来考虑窗体。所以他也锁定了这个物体

有时线程计时器会调用UIThread,如下所示:

lock (_lockobj)
{
    form.Invoke(new MethodInvoker(delegate
    {  // Do somethings on form }));
}
问题是,这个调用将“sleep”,因为表单计时器(它也睡眠)会对“\u lockobj”执行相同的锁定。所以出现了僵局(就是这样吗?)

我想我很清楚这里发生了什么,但如何解决这个问题。或者这是设计失败?或者可能有一些功能可以帮助我解决这个问题

问题是:当UIThread处于睡眠状态时,是否可能有非UIThread调用表单


谢谢。

这显然是一个僵局。持有锁时,不能调用其他线程

说明:

假设计时器线程获得锁,并将调用UI线程。在同一时刻,UI线程正在尝试获取锁,现在等待它被释放。因此,返回到第一个线程:对UI线程的调用无法完成,因为UI线程正在等待。僵局


我的建议是:去掉所有锁定,并将所有操作封送到UI线程中。这样,您的调用显然是串行的(所有调用都发生在同一个线程中!),因此不需要锁定。

这显然是一个死锁。持有锁时,不能调用其他线程

说明:

假设计时器线程获得锁,并将调用UI线程。在同一时刻,UI线程正在尝试获取锁,现在等待它被释放。因此,返回到第一个线程:对UI线程的调用无法完成,因为UI线程正在等待。僵局


我的建议是:去掉所有锁定,并将所有操作封送到UI线程中。这样,您的调用显然是串行的(所有调用都发生在同一个线程中!),因此无需锁定。

@Vlad。谢谢但是在UIThread中指定所有串行线程,而不是单独的线程,使这一切不会变慢吗?想想线程中发生了什么。计时器?是的,这是一个设计错误。有关设计中可能的更改,请参阅我答案中的更新。如何在代理内部使用lock(lockobj)。所以现在锁定/释放将只在UI线程上发生。好吧,所有的计算都应该在计时器线程中进行,没错。但是更新UI应该委托给没有锁的UI线程。@Aseem:如果所有锁都在UI线程中,则根本不需要锁。@Vlad。谢谢但是在UIThread中指定所有串行线程,而不是单独的线程,使这一切不会变慢吗?想想线程中发生了什么。计时器?是的,这是一个设计错误。有关设计中可能的更改,请参阅我答案中的更新。如何在代理内部使用lock(lockobj)。所以现在锁定/释放将只在UI线程上发生。好吧,所有的计算都应该在计时器线程中进行,没错。但是更新UI应该委托给没有锁的UI线程。@Aseem:如果所有锁都在UI线程中,则根本不需要锁。