public class EventService
{
public async Task InsertEventItemAsync(InsertEventItem request)
{
await SomeMethodThatUsesRestSharpToMakeAsynchronousWebApiCall(request);
}
public async Task<int> GetNumberOfEvents()
{
int result = await SomeOtherMethodThatUsesRestSharpToMakeAsynchronousWebApiCall();
return result;
}
}
public interface IFoo
{
void Bar();
int Baz();
}
public class Foo : IFoo
{
EventService _eventService;
public void Bar()
{
Task.Run(async() => await _eventService.InsertEventItemAsync());
}
public int Baz()
{
int result = Task.Run(async() => await this._eventService.GetNumberOfEvents()).Result;
return result;
}
}
對Foo.Bar()中的Task.Run的調用看起來不正確。 這是異步代碼的方法,在最近開始使用的項目的代碼庫中隨處可見。 我的假設是,異步lambda是爲了編譯代碼而編寫的。 我懷疑這是一個好方法。帶有異步lambda的Task.Run
我沒有太多的異步/等待經驗,但我認爲這將啓動一個新的ThreadPool線程並阻塞當前線程,直到任務完成ThreadPool線程上的runninng,這將導致比如果整個批次是同步的。
是代碼「錯誤」?
在我看來,可能會有一種厭惡(或可能是一個很好的理由)一直走異步。我是否應該嘗試使其完全異步或完全同步,而不是嘗試混合它們?
謝謝。
'Foo.Bar'將啓動一個在任務池上執行的新任務。沒有新的線程被創建。當任務異步執行時(「fire and forget」),'Foo.Bar'立即返回。代碼是否錯誤?這取決於你想達到什麼。您可以使用「普通」委託來替換異步委託,以便在生成的IL中進行輕微優化。 –
我已更新問題以顯示如何調用返回任務的方法。如果Task.Run是火,忘了,這是否意味着調用Task.Run(...)。結果阻止Foo。Baz立即返回,而是強迫它等到任務完成?這會增加死鎖的可能性嗎? –
dlarkin77
獲取任務的'Result'屬性將阻塞,直到任務完成,因此它不再是「火災和遺忘」。代碼中出現死鎖的可能性應爲零。如果不是,你需要解決死鎖的根本原因。但是,當您的代碼涉及到不可重入代碼的回調時,您可以通過在新任務/線程上安排這些回調來避免死鎖。你的問題似乎是關於異步和等待的一般理解,我建議你研究這個主題和/或寫一些簡單的代碼,以獲得更好的整體理解。 –