2013-04-13 73 views
13

我正在使用任務,異步並在我的WorkerRole(RoleEntryPoint)中等待。異步/等待azure角色導致角色回收

我有一些不明原因的回收利用,現在我發現如果有什麼東西在等候電話中運行很久,角色就會回收。要重現它,只需在Run方法中等待Task.Delay(60000)。

任何人都可以向我解釋爲什麼?

回答

22

Run方法必須塊。從the docs

如果您重寫Run方法,則代碼應該無限期地阻塞。如果Run方法返回,則通過引發Stopping事件並調用OnStop方法自動回收角色,以便在角色脫機之前執行關閉序列。

一個簡單的解決方法就是做:

public override void Run() 
{ 
    RunAsync().Wait(); 
} 

public async Task RunAsync() 
{ 
    while (true) 
    { 
    await Task.Delay(60000); 
    } 
} 

或者,你可以使用AsyncContext from my AsyncEx library

public override void Run() 
{ 
    AsyncContext.Run(async() => 
    { 
    while (true) 
    { 
     await Task.Delay(60000); 
    } 
    }); 
} 

您選擇哪個選項,Run應該async。這有點像控制檯應用程序Mainsee my blog for why async Main is not allowed)。

+0

如果運行是異步的,它不會無限期地阻塞?您的解決方案將在60秒後回收,正如其答案中顯示的那樣? –

+0

我更新了我的帖子,以包含一個鏈接到我的博客,爲什麼'async Main'不被允許。 'async Run'不允許出於同樣的原因。我的例子將在60秒後回收,因爲它從'Run'返回。如果你不想回收,不要從'運行'返回。 –

+0

在一般情況下可能不是一個好主意,但是如果你希望你的Run無限期地被阻塞,而不管RunAsync()(或者它最初執行的任何其他代碼)發生什麼,你總是可以[Thread.Sleep](http:///msdn.microsoft.com/en-us/library/d00bd51t.aspx)與[Timeout.Infinite](http://msdn.microsoft.com/en-us/library/system.threading.timeout.infinite.aspx) :) –

0

我建議像1000(ms)這樣的Task.Delay這個較低的值。我懷疑工作人員對健康檢查的反應不夠快。該角色然後被視爲無響應並重新啓動。

確保Run方法從來沒有像這樣的東西

while (true) 
{    
    Thread.Sleep(1000); 
} 

或者與你的情況Task.Delay返回。

+0

有關於此健康檢查的任何信息?它之前可以掛多久。我將它降低到1000毫秒,但只是想知道是什麼原因導致了這個問題,當我有一個長期掛異步方法。因爲我有一個異步方法,在服務器上設置一些需要幾分鐘的東西。等待它導致它回收,並且不會等待它運行正常,因爲run方法進入while(true)循環。 –

+0

不幸的是,我沒有來自任何官方來源的信息。任何人都得到了答案? – Pascal

相關問題