我为我正在开发的程序开发了一种简单的插件框架,并且作为它的一部分,我有抽象基类,插件意味着从中派生出来。例如:避免覆盖中的异步问题
public abstract class Plugin
{
public Task StartAsync()
{
Task.Run(Start);
}
protected abstract void Start();
}
美中不足的是,我真的很希望能够等待StartAsync和拥有一切完成(尽可能)的插件;很大程度上,我可以将所有内容都包含在try-catch中,并避免插件取消我的应用程序(我意识到我应该使用应用程序域,如果必须,我会)。
这是直到我在插件中定义的具有异步启动方法都工作正常:
public class MyPlugin
{
protected override async void Start()
{
// await some awaitable stuff
}
}
当然,我的抽象基类不等待启动(因为它不知道它会在编译时是异步的),所以如果MyPlugin抛出一个异常,框架没有机会去捕捉它。很显然,如果插件实现者做了一些异步的事情,但是这看起来像是一种非常简单的方式,只需在方法签名中添加异步,就可以轻松地完成自己的脚步。我意识到要求“等待,如果等待”操作员是不合理的,但我想知道是否有人对如何摆脱这个问题有任何想法(或者它不是一个问题,我也不合理)。
这里就是我想在我的脑海看到:
public abstract class Plugin
{
public Task StartAsync()
{
Task.Run(() => awaitif Start());
}
protected abstract void Start();
}
最后,我宁可不要让启动异步或返回任务,因为大多数的插件将可能是简单和同步。
这就是为什么你不使用'async void'方法。调用者无法知道操作何时完成,或者是否有任何错误。这是没有办法的;你需要返回一个'Task'(或其他具有相同信息的东西)给调用者来处理它。 – Servy
@Servy是的,这可能是公平的。但是,我无法阻止实施者指定异步。如果答案是,只需将[NotAsync]放在方法上,我会很高兴。 – Jeff
没有AppDomain,插件将会非常困难。祝你好运:) –