简体   繁体   English

如何在.net中除Main UI线程之外的其他线程上运行UI?

[英]How can I run UI on a thread other than the Main UI thread in .net?

I know there are other questions around this but most end up with the answer don't do what I am about to suggest. 我知道有关此还有其他问题,但是大多数最终答案都不是我要建议的。 So I know you aren't supposed to. 因此,我知道您不应该这样做。 The reason for this question is I want to do it anyway, how can I do it... 这个问题的原因是我仍然想这样做,我该怎么做...

Here is why I want to break the rules... 这就是为什么我要违反规则...

Let's say I have a complicated application, it's version 1 and we want our customers to submit errors to us in the event of crashes or hangs. 假设我有一个复杂的应用程序,它是版本1,我们希望我们的客户在发生崩溃或挂起时向我们提交错误。 Let's now say I have a button on the top of the main form they click to submit reports. 现在让我们说一下,他们单击要提交报告的主表单的顶部有一个按钮。

Let's now imagine that the application hung because of a deadlock... 现在让我们想象一下应用程序由于死锁而挂起了...

It would be nice if that small piece of UI and a handler for that button could live on a thread other than the main ui thread so that it isn't caught up in the deadlock. 如果那小部分的UI和该按钮的处理程序可以驻留在主ui线程以外的线程上,以免陷入僵局,那将是很好的。 When clicked it would gather all the call stacks for the other threads and submit them to our error reporting service. 单击后,它将收集其他线程的所有调用堆栈,并将它们提交给我们的错误报告服务。

Now, knowing the scenario, can this be done in .net? 现在,知道了这种情况,可以在.net中完成吗?

Yes, there is no magic in creating UI on another thread than the "main thread". 是的,在“主线程”之外的其他线程上创建UI并没有什么魔术。 The important rule to always keep in mind is to interact with that UI on the thread that created it. 始终牢记的重要规则是在创建UI的线程上与该UI进行交互。

Still, I feel that you are attacking this from the wrong angle. 不过,我仍然认为您是从错误的角度进行攻击。 You should probably instead make an effort to push all work off the main thread. 您可能应该改为将所有工作推离主线程。 That way you minimize the risk for that thread to freeze, and then you don't need to resort to unorthodox solutions for the error reporting. 这样,您可以最大程度地降低该线程冻结的风险,然后您就不必使用非传统的解决方案来报告错误了。

I have various cases of creating forms on non-main thread, and it works fine every time. 我在非主线程上创建表单的情况有很多种,每次都可以正常工作。

Create a new Thread , and show a Form from it. 创建一个新的Thread ,并显示一个Form New message loop will be created for that thread and everything will run fine. 将为该线程创建新的消息循环,一切运行正常。

What magic will you use to gather data from the crashed app and locked main thread, that's up to you :) 您将使用什么魔术来从崩溃的应用程序和锁定的主线程中收集数据,这取决于您:)

if application hung, your main message loop is dead, thus ui will not work. 如果应用程序挂起,则您的主消息循环已死,因此ui无法正常工作。 As workaround for your problem i'd consider usage of external application (another exe) which will be invoked in case of report 作为解决您的问题的方法,我将考虑使用外部应用程序(另一个exe),在报告情况下将调用该外部应用程序

in any case, if you want to invoke UI from other thread you should perform context switch In case of winforms, follow this answer 无论如何,如果要从其他线程调用UI,则应执行上下文切换 。对于winforms,请遵循以下答案

It sounds like you'd like to keep the UI alive, even when some other operation is mired in a deadlock. 听起来您想保持UI处于活动状态,即使某些其他操作陷入了僵局。 If so, perhaps Asynchronous Programming would be of use. 如果是这样,也许将使用异步编程 Using Async to manage a potentially hung up task would allow the remainder of the application to remain responsive. 使用异步管理潜在的挂断任务将使应用程序的其余部分保持响应。

we want our customers to submit errors to us in the event of crashes or hangs 我们希望客户在崩溃或挂起时向我们提交错误

You might also consider adding some degree if instrumentation/reporting, so that you'll have this data without requiring user input. 如果进行检测/报告,您还可以考虑添加某种程度的数据,以便无需用户输入即可获得此数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM