WinRT 是否仍然具有相同的旧 UI 线程限制?
在 WinForms 中,几乎所有 UI 都是特定于线程的。您必须使用 [STAThread]
才能使通用对话框正常工作,并且您无法(安全)从创建 UI 元素的线程以外的任何线程访问 UI 元素。据我所知,这是因为 Windows 就是这样工作的——窗口句柄是特定于线程的。
在 WPF 中,保留了这些相同的限制,因为最终它仍然构建在相同的 Windows API 之上,仍然是窗口句柄(尽管主要仅适用于顶级窗口)等。事实上,WPF 甚至使事情更多< /em> 限制性的,因为你甚至不能跨线程访问位图之类的东西。
现在 WinRT 出现了,这是一种访问 Windows 的全新方式——一种全新的、干净的状态。我们是否仍然坚持相同的旧线程限制(具体来说:只能从创建 UI 控件的线程中操作 UI 控件),还是他们已经开放了这个限制?
In WinForms, pretty much all your UI is thread-specific. You have to use [STAThread]
so that the common dialogs will work, and you can't (safely) access a UI element from any thread other than the one that created it. From what I've heard, that's because that's just how Windows works -- window handles are thread-specific.
In WPF, these same restrictions were kept, because ultimately it's still building on top of the same Windows API, still window handles (though mostly just for top-level windows), etc. In fact, WPF even made things more restrictive, because you can't even access things like bitmaps across threads.
Now along comes WinRT, a whole new way of accessing Windows -- a fresh, clean slate. Are we still stuck with the same old threading restrictions (specifically: only being able to manipulate a UI control from the thread that created it), or have they opened this up?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我期望它是相同的模型 - 但更更容易使用,至少在C#和VB中,具有新的异步处理,可以让你编写一个看起来同步的当需要等待长时间运行的任务完成然后再继续时,只使用“await”方法。
鉴于强调使异步代码更易于编写,对于 MS 来说,放弃要求同时单线程访问 UI 的效率将是令人惊讶的。
I would expect it to be the same model - but much easier to use, at least from C# and VB, with the new async handling which lets you write a synchronous-looking method which just uses "await" when it needs to wait for a long-running task to complete before proceeding.
Given the emphasis on making asynchronous code easier to write, it would be surprising for MS to forsake the efficiency of requiring single-threaded access to the UI at the same time.
线程模型是相同的。仍然存在单线程和多线程单元 (STA/MTA) 的概念,它必须通过调用 Ro初始化。它的行为在名称、参数和错误返回方面非常类似于 CoInitialize。用户界面线程是单线程的,已在 此视频。
The threading model is identical. There is still a notion of single threaded and multi-threaded apartments (STA/MTA), it must be initialized by a call to RoInitialize. Which behaves very much like CoInitialize in name, argument and error returns. The user interface thread is single threaded, confirmed at 36:00 in this video.
HTML/CSS UI 模型本质上是单线程的(直到最近 Web Workers 的出现,JS 才支持线程)。 Xaml 也是单线程的(因为开发人员确实很难向多线程 GUI 编写代码)。
The HTML/CSS UI model is inherently single threaded (until the advent of web workers recently, JS didn't support threads). Xaml is also single threaded (because it's really hard for developers to write code to a multithreaded GUI).
底层线程模型确实存在一些关键差异。当您的应用程序启动时,将创建一个 ASTA(应用程序 STA)来运行您的 UI 代码,如我在演讲中所示。此 ASTA 不允许重入 - 您在拨打电话时不会收到无关的电话。这是与 STA 的显着区别。
您可以创建异步工作项 - 请参阅 Windows.System.Threadpool 命名空间。这些工作项线程自动初始化为 MTA。正如 Larry 提到的,webworkers 是 JS 的等价概念。
您的 UI 组件是线程关联的。请参阅 Windows.UI.Core.CoreDispatcher class 了解如何在 UI 线程上执行代码的信息。您可以查看线程示例以获取一些示例代码,以通过异步操作更新 UI。
The underlying threading model does have some key differences. When your application starts, an ASTA (Application STA) is created to run your UI code as I showed in the talk. This ASTA does not allow reentrancy - you will not receive unrelated calls while making an outgoing call. This is a significant difference from STAs.
You are allowed to create async workitems - see the Windows.System.Threadpool namespace. These workitem threads are automatically initialized to MTA. As Larry mentioned, webworkers are the JS equivalent concept.
Your UI components are thread affined. See the Windows.UI.Core.CoreDispatcher class for information on how to execute code on the UI thread. You can check out the threading sample for some example code to update the UI from an async operation.
事情在一些非常重要的方面有所不同。
虽然底层线程模型确实是相同的,但您的问题通常与逻辑并发如何与 UI 配合使用有关,而开发人员在 Windows 8 中看到的内容将是新的。
正如您提到的大多数对话框以前被阻止。对于 Metro 应用程序,许多 UI 组件不会全部阻止。还记得有关 WinRT 异步的讨论吗?它也适用于 UI 组件。
例如,此 .NET 4 代码不一定会杀死您的硬盘,因为 UI 调用会在 Show 上阻塞(C# 示例):
在 Windows 8 Metro 中,许多 UI 组件(如 Windows.UI.Popups.MessageDialog)是由默认异步,因此 Show 调用将在检索用户输入之前立即(逻辑上)转到下一行代码。
当然,有一个基于等待/承诺设计模式(Javascript 示例)的优雅解决方案:
要点是,虽然线程模型没有改变,但当大多数人提到 UI 和线程时,他们正在考虑逻辑并发以及如何实现并发。它影响编程模型。
总的来说,我认为异步范式转变是一件积极的事情。它需要一些视角的转变,但它与其他平台在客户端和服务器端的发展方式是一致的。
Things are different in pretty important ways.
While it's true the underlying threading model is the same, your question is generally related to how logical concurrency works with UI, and with respect to this what developers see in Windows 8 will be new.
As you mention most dialogs previously blocked. For Metro apps many UI components do not block all. Remember the talk of WinRT being asynchronous? It applies to UI components also.
For example this .NET 4 code will not necessarily kill your harddrive because the UI call blocks on Show (C# example):
With Windows 8 Metro many UI components like Windows.UI.Popups.MessageDialog, are by default Asynchronous so the Show call would immediately (logically) fall through to the next line of code before the user input is retrieved.
Of course there is an elegant solution to this based on the await/promise design patterns (Javascript example):
The point is that while the threading model doesn't change, when most people mention UI and threading they are thinking about logical concurrency and how it affects the programming model.
Overall I think the asynchronous paradigm shift is a positive thing. It requires a bit of a shift in perspective, but it's consistent with the way other platforms are evolving on both the client and server sides.