C# 避免覆盖中的异步问题
我为我正在开发的一个程序开发了一种简单的插件框架,作为它的一部分,我有一些抽象的基类,插件就是从这些基类派生出来的。例如:C# 避免覆盖中的异步问题,c#,.net,asynchronous,async-await,C#,.net,Asynchronous,Async Await,我为我正在开发的一个程序开发了一种简单的插件框架,作为它的一部分,我有一些抽象的基类,插件就是从这些基类派生出来的。例如: public abstract class Plugin { public Task StartAsync() { Task.Run(Start); } protected abstract void Start(); } 问题是我真的希望能够等待StartAsync,并在插件中完成所有事情(尽可能);很大程度上,我可以把
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抛出异常,框架就没有机会捕获它。显然,如果插件实现者做了一些不被期待的异步操作,这也是正确的,但是这似乎是一种非常简单的方法,只需将异步添加到方法签名中,就可以让您一败涂地。我意识到要求一个“wait if waitable”接线员是不合理的,但我想知道是否有人想过如何让自己摆脱这个问题(或者这根本不是问题,我是不合理的)
以下是我试图在脑海中看到的:
public abstract class Plugin
{
public Task StartAsync()
{
Task.Run(() => awaitif Start());
}
protected abstract void Start();
}
最后,我不希望使Start异步或返回任务,因为大多数插件可能是简单和同步的。
任务
-接口中的返回方法在设计上与IDisposable
非常相似
我不希望使Start异步或返回任务,因为大多数插件都可能是简单和同步的
事实上,您的一些插件是异步的;因此,您应该有一个异步签名。同步插件很容易在实现结束时返回Task.FromResult(0)
考虑与
IDisposable
的相似性:如果您的一些插件是一次性的,那么您仍然应该从IDisposable
派生,只让非一次性插件实现一个空的Dispose这就是为什么您不使用异步void
方法的原因。调用方无法知道操作何时完成,或者是否有任何错误。这是没有办法的;您需要返回一个任务
(或其他具有相同信息的任务),以便调用方处理。@Servy是的,这可能是公平的。但是,我不能阻止实现者指定async。如果答案是,只要在方法上加上[NotAsync],我会很高兴的。没有AppDomains插件将非常困难。祝你好运:)你不应该让Async
方法仅仅在线程池上运行同步工作。是的,我已经解决了,谢谢!太棒了,我不知道结果。干杯