大家都知道,不允许从后台线程更新UI(或不?)
我做了一个小实验.这是一段代码:
var thread = new Thread(() => progressBar1.Increment(50)); thread.IsBackground = true; thread.Start(); thread.Join();
我将此代码放在一些按钮单击处理程序中.知道吗?我的进度条正在递增...从后台线程.现在我很困惑.我不明白它是如何可能的以及我做错了什么
我可以从后台线程更新UI,为什么?
最有可能的是,当您在调试器外部运行时,您可以这样做.这是因为该保护由Control.CheckForIllegalCrossThreadCalls属性控制.我们来看看参考源
private static bool checkForIllegalCrossThreadCalls = Debugger.IsAttached; public static bool CheckForIllegalCrossThreadCalls { get { return checkForIllegalCrossThreadCalls; } set { checkForIllegalCrossThreadCalls = value; } }
如您所见,只有在调试时才会默认启用此保护.
如果在Main
方法中添加以下行(之前Application.Run
)
Control.CheckForIllegalCrossThreadCalls = true;
你的代码将不再起作用.
大家都知道,不允许从后台线程更新UI
并非所有人都知道。但这是真的。从UI线程以外的线程更新大多数UI元素是错误的。
我不知道怎么可能
您将一堆沙子倒入汽车的油槽中。你不应该那样做。那么,您怎么可能这样做呢?好像要问一个奇怪的问题,不是吗?
是否需要汽车阻止您这样做?否。这样做时是否要求引擎停止运行?否。引擎最终会坏吗?大概。但不一定。
设计汽车的工程师认为您不会做错什么,因此他们没有内置任何安全系统来防止或检测此问题。
我究竟做错了什么?
您正在从后台线程更新UI。不要那样做 但是不需要运行时来提供可防止或检测到您的错误的安全系统。当您执行本不应该执行的操作时,不需要产生错误。它可以根据自己的意愿决定是否这样做。
或者,这样考虑。假设您正在实现运行时,以便它具有您认为具有的属性:运行时将始终检测错误的跨线程调用,并在发生错误时产生错误。这是一个功能。有人必须设计,编写,测试和维护该代码。代码是什么样的,以及与之相关的所有成本?