2013-11-01 109 views
0

我爲我正在開發的程序開發了一種簡單的插件框架,並且作爲它的一部分,我有抽象基類,插件意味着從中派生出來。例如:避免覆蓋中的異步問題

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

最後,我寧可不要讓啓動異步或返回任務,因爲大多數的插件將可能是簡單和同步。

+1

這就是爲什麼你不使用'async void'方法。調用者無法知道操作何時完成,或者是否有任何錯誤。這是沒有辦法的;你需要返回一個'Task'(或其他具有相同信息的東西)給調用者來處理它。 – Servy

+0

@Servy是的,這可能是公平的。但是,我無法阻止實施者指定異步。如果答案是,只需將[NotAsync]放在方法上,我會很高興。 – Jeff

+0

沒有AppDomain,插件將會非常困難。祝你好運:) –

回答

2

Task接口中的返回方法在設計上與IDisposable非常相似。

我寧願不開始異步或返回一個任務,因爲大多數插件將可能是簡單和同步的。

事實上,你的插件的一些是異步的;因此,你應該有一個異步簽名。在實施結束時,對return Task.FromResult(0)同步插件很容易。

考慮相似IDisposable:如果您插件的一些是一次性的,你還是應該從IDisposable獲得,只是有非一次性的插件實現空Dispose

+0

太棒了,我並不知道FromResult。乾杯。 – Jeff