如何在 STA 线程中运行某些东西?
在我的 WPF 应用程序中,我进行了一些异步通信(与服务器)。在回调函数中,我最终根据服务器的结果创建 InkPresenter 对象。这要求运行的线程是 STA,但目前显然不是。因此我得到以下异常:
无法创建程序集中定义的“InkPresenter”实例[..]调用线程必须是 STA,因为许多 UI 组件都需要它。
目前我的异步函数调用如下:
public void SearchForFooAsync(string searchString)
{
var caller = new Func<string, Foo>(_patientProxy.SearchForFoo);
caller.BeginInvoke(searchString, new AsyncCallback(SearchForFooCallbackMethod), null);
}
如何使回调(将执行 InkPresenter 创建)成为 STA?或者在新的 STA 线程中调用 XamlReader 解析。
public void SearchForFooCallbackMethod(IAsyncResult ar)
{
var foo = GetFooFromAsyncResult(ar);
var inkPresenter = XamlReader.Parse(foo.Xaml) as InkPresenter; // <!-- Requires STA
[..]
}
In my WPF application I do some async communication (with server). In the callback function I end up creating InkPresenter objects from the result from server. This requires the running thread to be STA, which apparently it currently isn't. Therefore I get the following exception:
Cannot create instance of 'InkPresenter' defined in assembly [..] The calling thread must be STA, because many UI components require this.
Currently my async function call is like this:
public void SearchForFooAsync(string searchString)
{
var caller = new Func<string, Foo>(_patientProxy.SearchForFoo);
caller.BeginInvoke(searchString, new AsyncCallback(SearchForFooCallbackMethod), null);
}
How can I make the callback - which will do the InkPresenter creation - be STA? Or invoke the XamlReader parsing in a new STA thread.
public void SearchForFooCallbackMethod(IAsyncResult ar)
{
var foo = GetFooFromAsyncResult(ar);
var inkPresenter = XamlReader.Parse(foo.Xaml) as InkPresenter; // <!-- Requires STA
[..]
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以像这样启动 STA 线程:
唯一的问题是您的结果对象必须以某种方式传递。您可以为此使用私有字段,或者深入将参数传递到线程中。在这里,我将 foo 数据设置在私有字段中,并启动 STA 线程来改变 inkpresenter!
希望这有帮助!
You can start STA Threads like so:
The only problem is that your result object must be passed along somehow.. You can use a private field for that, or dive into passing along parameters into threads. Here I set the foo data in a private field and start up the STA Thread to mutate the inkpresenter!
Hope this helps!
您可以使用 Dispatcher 类来执行UI 线程上的方法调用。 Dispatcher 提供静态属性 CurrentDispatcher 来获取线程的调度程序。
如果创建 InkPresenter 的类的对象是在 UI 线程上创建的,则 CurrentDispatcher 方法将返回 UI 线程的 Dispatcher。
在 Dispatcher 上,您可以调用 BeginInvoke 方法在线程上异步调用指定的委托。
You can use the Dispatcher class to execute the method call on the UI-Thread. The Dispatcher provides the static property CurrentDispatcher to get the dispatcher of a thread.
If your object of the class, that creates the InkPresenter, is created on the UI-Thread, then the CurrentDispatcher method returns the Dispatcher of the UI-Thread.
On the Dispatcher you can call the BeginInvoke-method to call the specified delegate asynchronously on the thread.
在 UI 线程上调用它应该足够了。因此,使用
BackgroundWorker
并在RunWorkerAsyncCompleted
上,您可以创建 inkPresenter。It should be good enough to call it on the UI thread. Therefore, use a
BackgroundWorker
and on theRunWorkerAsyncCompleted
, you can then do the creation of the inkPresenter.我刚刚使用以下命令从 STA 线程获取剪贴板内容。我想我会发帖也许将来可以帮助别人......
I have just used the following to get clipboard content from the STA thread. Thought I would post to maybe help someone in the future...
这有点黑客,但我会使用 XTATestRunner 所以你的代码看起来像:
作为奖励,它是可能的捕获 STA(或 MTA)线程中抛出的异常,如下所示:
It's a bit of a hack, but I would use XTATestRunner So your code will look like:
as a bonus it's possible to catch exceptions thrown in STA (or MTA) thread like this: