2016-12-14 117 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