有没有的MessageBox.show的非阻塞版本(或者类似的东西)? [英] Is there a non-blocking version of MessageBox.Show (or something like it)?

查看:1152
本文介绍了有没有的MessageBox.show的非阻塞版本(或者类似的东西)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我接受MUG4N的回答这个问题,我也想给一些人提出反对的批评作出回应。

I'm accepting MUG4N's answer to this question, and I also want to respond to some of the criticisms that were raised against it.

ChrisF说:

...你不能直接从后台线程的用户界面调用。

...you can't make UI calls directly from background threads.

这是一种全面的说法,而不是100%正确的。我只想指出几个事实:

This is a blanket statement, and is not 100% true. Let me just point out a few facts:

  1. 您实际上可以使用户界面调用的所有你想要的的,如果你设定 Control.CheckForIllegalCrossThreadCalls = FALSE 确认!的我听到你说。 不要永远做到这一点!的是,是的 - 但为什么?答案:因为有时这将破坏内存

  1. You can actually make UI calls all you want if you set Control.CheckForIllegalCrossThreadCalls = false. "Ack!" I hear you saying. "Don't ever do that!" Yes, yes -- but why? The answer: because sometimes this will corrupt memory.

System.Windows.Forms的控制类将不写入是线程安全的,所以有时从后台线程可能会破坏内存更新它们。但是,如果这只是的有时的发生,而不是的总是的,这是什么告诉我是这不是UI code的本身调用的,而是潜在的不安全的碰撞的UI code,可能会导致异常

The control classes in System.Windows.Forms are not written to be thread-safe, so sometimes updating them from background threads can corrupt memory. But if this only sometimes happens and not always, what this tells me is that it is not the calling of UI code per se, but rather the potentially unsafe collision of UI code that can cause exceptions.

要加强点1,考虑一下:安全的方式从后台线程调用UI code是这样做的使用 Control.Invoke Control.BeginInvoke ,对不对? 但是,这的的一个用户界面调用;这只是的的UI调用我们应该做,如果我们正在更新从一个非GUI线程的GUI。我的意思是,显然,它不是简单地调用控制对象的任何的方法从外螺纹,那将造成混乱(如果是这样的话,那么我们甚至不能称之为调用键,我们就可以完全被卡住)。再次,它是不能安全地发生的同时,将证明破坏性独立UI调用的潜在冲突。

To reinforce point 1, consider this: the "safe" way to invoke UI code from a background thread is to do so using Control.Invoke or Control.BeginInvoke, right? But this is a UI call; it's just the UI call we're supposed to make if we're updating the GUI from a non-GUI thread. What I mean is, clearly, it is not simply invoking "any" method on a Control object from an outside thread that's going to cause chaos (if that were the case, then we couldn't even call Invoke and we'd be stuck completely). Again, it's the potential collision of separate UI calls that cannot safely occur simultaneously that will prove destructive.

保持上述两点考虑,问自己:为什么会是不安全的的MessageBox.show 从非GUI线程中调用?一个完全独立的表格创建并显示;其属性不以任何方式与任何其他现有的GUI对象交互;事实上,它不能被访问的的任何地方的中的任何方式的,除了一个:从调用线程,它访问了的DialogResult 财产(只有通过显示方法的返回值)。

Keeping the above two points in mind, ask yourself: why would it be unsafe to call MessageBox.Show from a non-GUI thread? A completely separate Form is created and displayed; its properties do not in any way interact with any other existing GUI object; in fact, it cannot be accessed anywhere in any manner, except for one: from the calling thread, which accesses its DialogResult property (and only that via the Show method's return value).

顺动。康拉德阿尔布雷希特说:

Moving along. Conrad Albrecht said:

...给出(这其中不成立,但我无法反驳)的说法,显示()设置于丹的ref'd话题了自己的消息泵,...

...given the assertion that Show() sets up its own message pump in Dan's ref'd topic, (which was not substantiated, but which I can't refute)...

这是一个完全公平的点(虽然我个人认为贾里德面值在足够高的自尊,我不会一般倾向于的疑问的是什么,他说)。在任何情况下,通过偷看的MessageBox.show 方法反射揭示了这个片段:

This is a totally fair point (though I personally hold Jared Par in high enough esteem that I wouldn't generally be inclined to doubt what he says). In any case, a peek at the MessageBox.Show method through Reflector reveals this snippet:

Application.BeginModalMessageLoop();
try
{
    result = Win32ToDialogResult(SafeNativeMethods.MessageBox(new HandleRef(owner, zero), text, caption, type));
}
finally
{
    Application.EndModalMessageLoop();
    UnsafeNativeMethods.ThemingScope.Deactivate(userCookie);
}

还有一个不期而遇的 Application.BeginModalMessageLoop 方法揭示了这一点:

A further peek into the Application.BeginModalMessageLoop method reveals this:

ThreadContext.FromCurrent().BeginModalMessageLoop(null);

和本 ThreadContext.FromCurrent ,依次为:

// [Reflector shows that currentThreadContext is a ThreadStatic member. -Dan]
if (currentThreadContext == null)
{
    currentThreadContext = new Application.ThreadContext();
}
return currentThreadContext;

我不知道有足够的了解,这些低级别的Windows构建要充分认识这项code,但在我看来,是什么贾里德在说我在我的旧注释的参考答案证明(好奇的读者:<一href="http://stackoverflow.com/questions/559252/does-messagebox-show-automatically-marshall-to-the-ui-thread">Does的MessageBox.show()自动马歇尔到UI线程?)。

所以,是的。我完全在这一个与MUG4N协议。

So, yeah. I am totally in agreement with MUG4N on this one.

(如果任何人都可以令人信服地辩称,我还是错了这里,请说出来。虽然我觉得我做了一个pretty的很好的例子,为什么我相信MUG4N是正确的,我显然不是100%肯定。)

(If anyone can convincingly argue that I am still mistaken here, please speak up. Although I feel I've made a pretty good case for why I believe MUG4N is right, I'm obviously not 100% certain.)

通常情况下,你只是想通知用户已发生些什么,但真的没有必要从他们的任何输入。在这种常见的情况,我有时会看到code是这样的:

Often you just want to notify the user that something has occurred, but there's really no need for any input from them. In this common scenario, I sometimes see code like this:

MessageBox.Show("Something has occurred", "Something", MessageBoxButtons.OK);

这code,因为大家都知道,导致一个小的弹出窗口出现,只有一个确定按钮。现在,这里的东西:这code块(UI线程)。但在案件的绝大多数,在我看来,如果你的只有的有确定按钮,有很少需要阻止。 (不阻止通常接收来自用户的某些输入的目的是什么?如果用户的只有的选择是OK,在这个典型的案例,不堵pretty的意义? )

This code, as we all know, causes a little pop-up window to appear with only an OK button. Now here's the thing: this code blocks (the UI thread). But in the vast majority of cases, it seems to me, if you only have an OK button, there's very little need to block. (Isn't the purpose of blocking typically to receive some input from the user? And if the user's only choice is "OK," in this typical case, isn't blocking pretty pointless?)

很显然,我可以只写我自己的小形式,基本上做什么的MessageBox.show 确实,除了它没有返回值(无的DialogResult ),并不会阻止。但我只是想知道,如果这样的事情已经存在,我不知道。

Obviously I could just write my own little form that does basically exactly what MessageBox.Show does, except that it returns nothing (no DialogResult) and doesn't block. But I was just wondering if something like this exists already that I didn't know about.

推荐答案

您需要使用多线程来执行这个任务,其中一个线程(主线程)会做处理,而另一个线程将被用于显示消息框。

You need to use multi threading to perform this task in which one thread (the main thread) will do the processing and the other thread will be used to show the messagebox.

这篇关于有没有的MessageBox.show的非阻塞版本(或者类似的东西)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆