2016-12-14 148 views
3

是否有可能做這樣的事情,或者它是危險/不好的做法?如果不好,還有另外一種方法可以解決這個問題嗎?C#嵌套異步方法

void methodA() 
{ 
    while (something) { 
     // do stuff 
     methodB(); 
    } 
} 

async Task methodB() 
{ 
    bool b = await methodC(); 
    // do something with b 
} 

async Task<bool> methodC() 
{ 
    await Task.Delay(1000); 
} 

我試圖實現是methodA能夠做的東西,而methodC是在IO等待。因此,與此我希望methodC將返回methodB而忙碌,因爲methodB等待答案,它將返回methodA,其中methodA可以繼續工作的東西,也許叫methodB再次

+0

「東西」究竟是什麼,爲什麼你不等待'methodB'的調用? –

+0

這不僅是不壞,它有點整個Async。畢竟Task.Delay只是一個正在等待另一種方法的方法(換句話說,Task.Delay什麼也不做,你不能做C#程序員)。這並不是說你不能犯錯誤。異步是另一層複雜性。 – NPSF3000

+0

@JustinNiessner我們有一個線程在等待新消息的循環中旋轉,一旦它接收到消息,它將發送進程一些東西並將其發送到服務器(異步調用,因此task.delay),我想知道如果沒有引入任何不好的東西(例如死鎖)就可以用這種方式進行編程 –

回答

0

您可能完全可以接受您不等待MethodA中的MethodB(只要您在MethodA中執行其他任務之前並不真正需要MethodB,並且您小心避免競爭條件)。還有其他幾個選項。你可能想看看Task.ContinueWith

,我在這裏想了很多的第二個選項:

List<Task> tasks = new List<Task>(); 
while (something) { 
     // do stuff 
     // This doesn't actually wait for methodB - it just keeps going 
     Task methodBTask = methodB(); 
     tasks.Add(methodBTask); 
    } 

// Wait for all of the tasks we started to complete 
await Task.WhenAll(tasks); 
// ... 

我認爲這應該做你想要什麼,它不會是容易出現競爭情況。基本上,這會在MethodB中啓動任何操作,但是很多時候都是你想要的,然後等待它們全部「排隊」完成。

+0

對不起,我有一個錯字,我的意思是調用'methodC',但我並不是說要在'methodA'內部等待'methodB',實際上,我想'methodA'能夠再次調用'methodB',即使另一個調用'methodB'還沒有完成 –

+0

@SvetAngelov我編輯過。我的新樣本應該完全符合你的想法。 – EJoshuaS

0

沒錯,這就是標準實踐。

async Task methodA() 
{ 
    while (something) 
    { 
     Task b = methodB(); 
     // do stuff 
     await b; 
    } 
} 

需要提醒的是,你在這裏引入併發,所以你需要確保你沒有與平行,而正在執行執行任何線程問題。

+0

他們將在單獨的數據上工作。就目前來說,我們使用'Task.Run'來做這件事情,而且我覺得自從我們在做IO工作時,使用async/await會更有意義。它聽起來不錯嗎? –

+0

不知道你的代碼和剛剛等待methodB()的區別是什麼?他沒有在任何地方使用b。在他的例子中b是布爾值,在你的這是任務。 「做東西」會阻止循環。爲什麼它是upvoted? EJoshuaS的答案是正確的。 – MistyK