【发布时间】:2011-04-14 09:29:12
【问题描述】:
我想象 WndProc 是在另一个线程而不是主 UI 线程上调用的。
我是对的,所以我认为只需在表单上使用 InvokeRequired 和 Invoke 就足以在 UI 线程上显示消息框。
我错了。我不明白为什么。
我该如何解决这个问题?我在谷歌上四处寻找,但没有找到解决方案。
我要做的只是在剪贴板更改时引发自定义事件 (ClipboardUpdate)
消息框只是一个测试但没有工作,而只是更改字符串(表单的私有字段)之类的东西是有效的,但这种行为不是一件好事,因为它是不安全的跨线程操作方式。
更新 1:
我没有这里的代码,因为我是在朋友的计算机上创建的,但是我可以准确地解释我写的内容,因为很短。 我用visual studio创建了一个基本的winform,没有任何东西。 我使用 AddClipboardFormatListener (互操作,但它作为一个函数很容易,返回 int 并接受 IntPtr)函数(在 Windows 7 操作系统上)只检测 WM_CLIPBOARDUPDATE 消息,在 winproc 内(一个简单的 if,*if (e.Msg == ClipboardExtension .WM_CLIPBOARDUPDATE) DoClipboardUpdate();*).
现在 DoClipboardUpdate 这样做:
if (InvokeRequired)
Invoke(new VoidDelegate(OnClipboardUpdate));//Void delegate it's a delegate that doesn't take
// Params and returns void
else
OnClipboardUpdate();
很简单吧? OnClipboardUpdate 只需这样做:
if (ClipboardUpdate != null) ClipboardUpdate(null,EventArgs.Empty);
ClipboardUpdate 是这样声明的事件:
public event EventHandler<EventArgs> ClipboardUpdate;
最后,订阅 ClipboardUpdate 事件的唯一方法里面有这个:
MessageBox.Show("test");
当我运行代码时会发生什么?该事件被触发(我尝试了一个异常并且它有效)并且消息框没有弹出,但是我不能再与我的表单交互,因为它的行为就像打开了一个弹出窗口(这是“正常”行为时你在不同的线程上打开一个弹出窗口,这就是我这么说的原因。
关于如何解决这个问题的任何建议?
【问题讨论】:
-
如果您使用 .NET 4,请考虑使用任务库而不是 theads.. 就您而言 - 您不能直接从后台线程显示 MessageBox.. 可能会将其加入 UI 线程首先在 UI 线程上显示 MessageBox...
-
您是如何得出该表单的 WndProc 是在非 UI 线程上执行的结论的?据我所知(并根据我所做的测试)它在 UI 线程上执行。
-
WndProc方法在 UI 线程上被调用和执行。从该代码显示消息框不是问题。不存在跨线程问题。发布您拥有的不起作用的代码。 -
@Fredrik 更新了主要问题以解释我的工作
标签: c# winforms multithreading wndproc