问题描述
当我使用Office.Interop
库重构一些旧的C#代码以生成文档时,我发现了这一点,并且由于它在调用函数时使用UI上下文而阻塞了它
While I was refactoring some old C# code for document generation with Office.Interop
library I found this and because of it was using UI context when function were called from it it was blocking it
示例
private void btnFooClick(object sender, EventArgs e)
{
bool documentGenerated = chckBox.Checked ? updateDoc() : newDoc();
if(documentGenerated){
//do something
}
}
决定进行更改,以减少阻止用户界面的行为
Decided to change it like that to reduce from blocking UI
private async void btnFooClick(object sender, EventArgs e)
{
bool documentGenerated; = chckBox.Checked ? updateDoc() : newDoc();
if(chckBox.Checked)
{
documentGenerated = await Task.Run(() => updateDoc()).ConfigureAwait(false);
}
else
{
documentGenerated = await Task.Run(() => newDoc()).ConfigureAwait(false);
}
if(documentGenerated){
//do something
}
}
它抛出了这样的错误
为什么会发生这种情况以及可能的解决方法?
Why does it happen and what is possible workaround?
推荐答案
通过Interop访问的COM组件要求调用线程是STA线程,但在您的情况下不是STA.使用STA可以通过多个线程访问该组件.您可以在了解和使用COM线程模型中了解有关为什么需要STA的更多信息. a>您可以按照 answer 中的建议,在Task类上创建扩展方法通过使用任务的Interop来实现COM组件.
The COM components accessed through Interop require the calling thread to be a STA thread but in your case it is not STA. Using STA the component could be accessed through multiple threads. You can read more about why STA is required in Understanding and Using COM Threading Models You can make a extention method on Task class as suggested in this answer to call the COM component through Interop using task.
public static Task<T> StartSTATask<T>(Func<T> func)
{
var tcs = new TaskCompletionSource<T>();
Thread thread = new Thread(() =>
{
try
{
tcs.SetResult(func());
}
catch (Exception e)
{
tcs.SetException(e);
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
return tcs.Task;
}
您还可以使用Thread代替task,您必须像thread.SetApartmentState(ApartmentState.STA)
You can also use Thread instead of task, you have to set the ApartmentState to STA like thread.SetApartmentState(ApartmentState.STA)
这篇关于从UI线程执行Task.Run会引发STA错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!