.net 如果在C#应用程序的UI线程上调用Monitor.Enter()是否允许处理事件?

.net 如果在C#应用程序的UI线程上调用Monitor.Enter()是否允许处理事件?,.net,locking,.net,Locking,我正在调查一个堆栈跟踪(在调试时看到),该跟踪看起来如下所示: MyUtility.AcquireLock() [some of our code] MyControl.OnPaint(PaintEventArgs e) [some external WinForms (painting) code] (native code corresponding to Monitor.Enter(object)) MyUtility.AcquireLock() [some of our code] My

我正在调查一个堆栈跟踪(在调试时看到),该跟踪看起来如下所示:

MyUtility.AcquireLock()
[some of our code]
MyControl.OnPaint(PaintEventArgs e)
[some external WinForms (painting) code]
(native code corresponding to Monitor.Enter(object))
MyUtility.AcquireLock()
[some of our code]
MyControl.OnLoad(EventArgs e)
这有意义吗?还是有什么东西把我的堆栈跟踪搞砸了


我几乎(但不是完全)确定,没有其他线程持有此锁,我正在尝试获取(通过使用Monitor.Enter())。

确实如此。Monitor.Enter执行所谓的可警报等待。只有少数人知道这在2011年意味着什么,因为这是一个模糊的概念。这意味着线程将在等待时泵送窗口消息。是的,这看起来很奇怪。你目前正处于一个非常黑暗的痛苦世界,因为你正面临着不确定的再入问题


通往光明之路是根本不要等待gui线程!启动一个后台线程,可能是一个后台工作人员。

确实如此。Monitor.Enter执行所谓的可警报等待。只有少数人知道这在2011年意味着什么,因为这是一个模糊的概念。这意味着线程将在等待时泵送窗口消息。是的,这看起来很奇怪。你目前正处于一个非常黑暗的痛苦世界,因为你正面临着不确定的再入问题


通往光明之路是根本不要等待gui线程!启动一个后台线程,可能是一个后台工作人员。

是否
等待
执行相同的操作?如果一个人想点击消息泵,并且如果有足够多的控件被禁用以防止意外递归,是否可以使用带超时的等待作为睡眠的替代方法?@supercat supercat我不知道。无论如何,我不建议等待UI线程。即使它因泵送等待而工作,由于可重入性,它也会使应用程序设计复杂化。有更好的选项可用(如简单工作线程或异步等待)。在某些情况下,按钮的自然行为是在UI线程上执行一些操作,间隔时间很短[例如,在显示器上短暂突出显示控件,时间足够长,可以看到]。为需要
BeginInvoke
UI线程上的控件来执行可视化更新的内容创建后台任务似乎有点过火。@我强烈反对。今天有很多简单的技术可以实现这一点(例如异步,任务是一种比BeginInvoke更简单的调用)。我描述的场景可以编码为
{LockUi();BigButton.Color=Color.Green;UiSleep(100);BigButton.Color=Color.Red;UnlockUi();}
我不熟悉您描述的技术,但是我不知道他们会变得多么容易。
等待
做同样的事情吗?如果一个人想点击消息泵,并且如果有足够多的控件被禁用以防止意外递归,是否可以使用带超时的等待作为睡眠的替代方法?@supercat supercat我不知道。无论如何,我不建议等待UI线程。即使它因泵送等待而工作,由于可重入性,它也会使应用程序设计复杂化。有更好的选项可用(如简单工作线程或异步等待)。在某些情况下,按钮的自然行为是在UI线程上执行一些操作,间隔时间很短[例如,在显示器上短暂突出显示控件,时间足够长,可以看到]。为需要
BeginInvoke
UI线程上的控件来执行可视化更新的内容创建后台任务似乎有点过火。@我强烈反对。今天有很多简单的技术可以实现这一点(例如异步,任务是一种比BeginInvoke更简单的调用)。我描述的场景可以编码为
{LockUi();BigButton.Color=Color.Green;UiSleep(100);BigButton.Color=Color.Red;UnlockUi();}
我不熟悉您描述的技术,但我不知道他们能轻松多少。