使用任务时如何在STA线程上运行

时间:2014-05-12 11:55:42

标签: c# multithreading winforms vsto

我正在VS2010中开发VSTO Outlook加载项。在ThisAddIn_Startup方法(在插件启动时调用)中,我的代码需要检查Outlook是否在公司网络上运行。如果Outlook未在网络上运行,则需要大约3秒钟才能回复。因此,我将代码包装在一个Task中,使其运行Async以确保它在检查时不会挂起Outlook。

e.g。

bool onNetwork = false;
Task task = Task.Factory.StartNew(() =>
{
    onNetwork = IsConnectedToNetwork();
});

完成检查后,需要加载并显示相关表格。 所以我将代码更改为:

Task task = Task.Factory.StartNew(() =>
{
    if (IsConnectedToNetwork())
    {
        OnNetworkForm onNetworkForm = new OnNetworkForm();
        onNetworkForm.Show();
    }
    else
    {
        OffNetworkForm offNetworkForm = new OffNetworkForm();
        offNetworkForm.Show();
    }
});

但是需要在UI线程上加载Forms。否则,当我尝试加载并显示带有消息的表单时,我会得到InvalidOptionationException

  

调用线程必须是STA,因为许多UI组件都需要   此

我的问题是如何在UI线程上加载表单?

请注意

我不能使用等待,因为它是C#5.0而VS 2010不支持C#5.0。 并且ThisAddin类不是控件,因此没有BeginInvokeInvoke方法可用。

1 个答案:

答案 0 :(得分:5)

使用'老式'主题的一个例子:

    var task = new Task<bool>(IsConnectedToNetwork);
    task.ContinueWith(res =>
        {
            bool onNetwork = res.Result;
            var thread = new Thread(() =>
            {
                Form frm = onNetwork ? (Form)new OnNetworkForm() : new OffNetworkForm();
                frm.ShowDialog();
            });
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        });
    task.Start();