I've developed a sort of simple plug-in framework for a program I'm working on and as part of it I have abstract base classes that plug-ins are meant to be derived from. For example:
public abstract class Plugin
{
public Task StartAsync()
{
Task.Run(Start);
}
protected abstract void Start();
}
The catch is that I really would like to be able to await StartAsync and have everything completed (to the extent possible) in the plug-in; largely so I can wrap everything in a try-catch and avoid the plugin taking down my app (I realize I should probably be using app domains and if I have to, I will).
This was all working fine until I defined a plug-in with an async Start method:
public class MyPlugin
{
protected override async void Start()
{
// await some awaitable stuff
}
}
Of course, my abstract base class is not awaiting Start (because it doesn't know it's going to be async at compile time) so if MyPlugin throws an exception, the framework has no opportunity to catch it. Clearly this would also be true if the plug-in implementer did something asynchronous that was un-awaited but this seems like a very easy way to shoot yourself in the foot, simply by adding async to the method signature. I realize asking for an "await if awaitable" operator is unreasonable but I wondered if anyone had any thoughts on how to get myself out of this problem (or is it not a problem at all and I'm being unreasonable).
Here's what I'm trying to see in my head:
public abstract class Plugin
{
public Task StartAsync()
{
Task.Run(() => awaitif Start());
}
protected abstract void Start();
}
Lastly, I would rather not make Start async or return a Task as the majority of plug-ins will likely be simple and synchronous.