我有一个系统,它使用system.AddIn(MAF)在单独的进程中托管加载项。在插件中,我想使用一些利用异步和等待的代码。
由于MAF使用远程处理来跨进程通信,并且我们对这种通信几乎没有控制权,因此我正在努力确定在不存在死锁风险的情况下使用异步代码的最佳方式。
例如,现在我有一个合同,它定义了这样一种方法:
[AddInContract]
public interface IWorker : IContract
{
string DoWork(string workToDo);
}
在DoWork
的AddIn实现中,我希望能够使用异步API。如果我能在AddInAdapter和HostAdapter中想出一种从字符串转换为Task<string>
的方法,那就太好了,但我想确保我没有为自己设置死锁。
我想将我的视图合同定义为:
[System.AddIn.Pipeline.AddInBaseAttribute()]
public interface IWorker
{
Task<string> DoWork(string workToDo);
}
然后,在合同中执行以下操作以查看适配器是否安全:
public virtual string DoWork(string workToDo)
{
var t = _view.DoWork(Contracts.AddInSideAdapters.DoWorkAddInAdapter.ContractToViewAdapter(workToDo)).ConfigureAwait(false);
return t.GetAwaiter().GetResult();
}
我知道这个问题还有几个月的时间,但如果你愿意在与主机相同的AppDomain中加载你的加载项,你就可以一直通过你的任务。我最近刚刚做了这件事,并在GitHub上发布了我的测试项目:https://github.com/middas/AddinProofOfConcept/blob/master/AddinProofOfConcept/ConsoleHost/Program.cs
这是指向插件的主机使用者的链接,您将看到最后一个测试是一个异步任务,它也有一个CancellationToken。如果任务被取消,而不是等待AddIn设置的30秒,则测试通过。