gpt4 book ai didi

.net - 是否有 MessageBox.Show 的非阻塞版本(或类似的版本)?

转载 作者:行者123 更新时间:2023-12-03 03:11:15 26 4
gpt4 key购买 nike

久违的更新
我接受 MUG4N 对这个问题的回答,我也想回应一些针对它提出的批评。
ChrisF 说:

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


这是一个笼统的陈述,并非 100% 正确。让我指出几个事实:
  • 如果您设置 Control.CheckForIllegalCrossThreadCalls = false,您实际上可以进行任何您想要的 UI 调用。 . “啊!”我听到你说。 “不要 永远 那样做!”是的,是的——但是为什么 ?答案:因为有时这会破坏内存。System.Windows.Forms 中的控制类没有写成线程安全的,所以有时从后台线程更新它们会损坏内存。但是,如果这只是偶尔发生而不总是发生,那么这告诉我的是 不是 UI 代码本身的调用,而是 UI 代码的潜在不安全冲突可能导致异常 .
  • 为了强化第 1 点,考虑一下:从后台线程调用 UI 代码的“安全”方式是使用 Control.InvokeControl.BeginInvoke , 对? 但这是一个 UI 调用 ;如果我们从非 GUI 线程更新 GUI,这只是我们应该进行的 UI 调用。我的意思是,很明显,它不仅仅是在 Control 上调用“任何”方法。来自外部线程的对象会导致困惑(如果是这种情况,那么我们甚至不能调用 Invoke 并且我们会完全被卡住)。同样,不能安全地同时发生的单独 UI 调用的潜在冲突将证明是破坏性的。
  • 牢记以上两点,问问自己:为什么调用 MessageBox.Show 会不安全?来自非 GUI 线程?一个完全独立的Form被创建和显示;它的属性不以任何方式与任何其他现有的 GUI 对象交互;事实上,它不能以任何方式在任何地方访问,除了一个:从调用线程,它访问它的DialogResult。属性(只有通过 Show 方法的返回值)。

  • 一起前进。康拉德·阿尔布雷希特说:

    ...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)...


    这是一个完全公平的观点(尽管我个人对 Jared Par 有足够的尊重,以至于我通常不会怀疑他所说的话)。无论如何,看看 MessageBox.Show方法通过 Reflector揭示了这个片段:
    Application.BeginModalMessageLoop();
    try
    {
    result = Win32ToDialogResult(SafeNativeMethods.MessageBox(new HandleRef(owner, zero), text, caption, type));
    }
    finally
    {
    Application.EndModalMessageLoop();
    UnsafeNativeMethods.ThemingScope.Deactivate(userCookie);
    }
    进一步了解 Application.BeginModalMessageLoop方法揭示了这一点:
    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 结构了解得不够多,无法完全理解这段代码,但在我看来,这证明了 Jared 在我在旧评论中引用的答案中所说的话(对于好奇的读者: Does MessageBox.Show() automatically marshall to the UI Thread? )。
    是的。在这一点上,我完全同意 MUG4N。
    (如果有人可以令人信服地争辩说我在这里仍然是错误的,请说出来。虽然我觉得我已经为为什么我认为 MUG4N 是正确的做了一个很好的理由,但我显然不是 100% 确定的。)

    原始问题
    通常你只是想通知用户发生了一些事情,但实际上不需要他们的任何输入。在这种常见情况下,我有时会看到如下代码:
    MessageBox.Show("Something has occurred", "Something", MessageBoxButtons.OK);
    众所周知,这段代码会导致出现一个小弹出窗口,其中只有 。好的按钮。现在事情是这样的:这段代码块(UI 线程)。但在绝大多数情况下,在我看来,如果您只有 好的按钮,几乎不需要阻止。 (阻塞的目的通常不是为了接收用户的一些输入吗?如果用户的唯一选择是“OK”,在这种典型情况下,阻塞不是毫无意义吗?)
    显然,我可以编写自己的小表单,它基本上完全符合 MessageBox.Show 的功能。确实如此,除了它什么都不返回(没有 DialogResult )并且不阻塞。但我只是想知道这样的事情是否已经存在而我不知道。

    最佳答案

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

    关于.net - 是否有 MessageBox.Show 的非阻塞版本(或类似的版本)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2834101/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com