如何在STA线程中运行某些东西?

sti*_*k81 38 .net c# wpf 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);
}
Run Code Online (Sandbox Code Playgroud)

如何进行回调 - 这将创建InkPresenter - 是STA吗?或者在新的STA线程中调用XamlReader解析.

public void SearchForFooCallbackMethod(IAsyncResult ar)
{
    var foo = GetFooFromAsyncResult(ar); 
    var inkPresenter = XamlReader.Parse(foo.Xaml) as InkPresenter; // <!-- Requires STA
    [..]
}
Run Code Online (Sandbox Code Playgroud)

Arc*_*rus 58

您可以像这样启动STA线程:

    Thread thread = new Thread(MethodWhichRequiresSTA);
    thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
    thread.Start(); 
    thread.Join(); //Wait for the thread to end
Run Code Online (Sandbox Code Playgroud)

唯一的问题是你的结果对象必须以某种方式传递..你可以使用私有字段,或潜入传递参数到线程.在这里,我将foo数据设置在私有字段中,并启动STA线程以改变inkpresenter!

private var foo;
public void SearchForFooCallbackMethod(IAsyncResult ar)
{
    foo = GetFooFromAsyncResult(ar); 
    Thread thread = new Thread(ProcessInkPresenter);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join(); 
}

private void ProcessInkPresenter()
{
    var inkPresenter = XamlReader.Parse(foo.Xaml) as InkPresenter;
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!


Jeh*_*hof 11

您可以使用Dipatcher类在UI-Thread上执行方法调用.Dispatcher提供静态属性CurrentDispatcher来获取线程的调度程序.

如果创建InkPresenter的类的对象是在UI-Thread上创建的,那么CurrentDispatcher方法将返回UI-Thread的Dispatcher.

在Dispatcher上,您可以调用BeginInvoke方法在线程上异步调用指定的委托.