【问题标题】:Using async/await with the Managed Addin Framework将 async/await 与托管插件框架一起使用
【发布时间】:2015-11-22 04:10:05
【问题描述】:

我有一个使用System.AddIn (MAF) 在不同进程中托管插件的系统。在插件中,我想使用一些利用 async 和 await 的代码。

由于 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();
}

【问题讨论】:

  • 如果你的 DoWork 不是异步的,那么就不要做异步...否则只是await 并且不要使用任何其他异步方法(GetAwaiter()、GetResult() .Wait , 结果)
  • 那么,如果需要使用只公开异步端点的 API,我只需在这些调用上调用 .Result()?我问的原因是我希望开发插件的人不必考虑是否异步。
  • @PeterDuniho 如果您了解 MAF,那么“查看合约”和“查看适配器的合约”是在应用于此问题时提供足够的上下文来理解 Task&lt;string&gt; 如何转换为string 在 MAF 管道中。我认为这是一个非常具体和有针对性的问题,适合 StackOverflow,但可能仅限于少数有专业知识的人来回答这个问题。
  • 在 MAF 中没有跨应用程序域/进程编组任务的直接方法。如果您要自己实现插件模型,那么很少有文章展示如何跨应用程序域进行任务编组。

标签: c# async-await maf


【解决方案1】:

我知道这个问题已经有几个月的历史了,但是如果您愿意在与主机相同的 AppDomain 中加载您的插件,您将能够一直传递您的任务。我最近刚刚做了这个并将我的测试项目发布在 GitHub 上: https://github.com/middas/AddinProofOfConcept/blob/master/AddinProofOfConcept/ConsoleHost/Program.cs
这是 AddIn 的主机使用者的链接,您将看到最后一个测试是一个异步任务,它也有一个 CancellationToken。如果任务被取消而不是等待插件设置的 30 秒,则测试通过。

【讨论】:

  • 感谢您的回答,但我们使用 MAF 的一大原因是进程隔离。将它们加载到同一个 AppDomain 对我们来说是不可能的。
  • 我想了很多,这往往是选择 MAF 的一个重要原因,值得向其他可能遇到此问题的人指出这一点。
  • 在同一个应用程序域中加载第三方插件实际上不是一个好主意。虽然我知道它确实简化了开发,但也带来了风险。
猜你喜欢
  • 1970-01-01
  • 2017-11-05
  • 2019-04-15
  • 2014-06-19
  • 2018-01-14
  • 2018-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多