C#嵌套异步方法

时间:2016-12-14 18:46:25

标签: c# async-await

可以做这样的事情,还是危险/不良做法?如果它不好,那么另一种方法是什么呢?

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

2 个答案:

答案 0 :(得分:0)

是的,这是标准做法。

<!DOCTYPE html>
<html>
<head>
    <meta charset= "UTF-8">
    <link rel="stylesheet" type="text/css" href="style.css">
    <title>Star rating using pure CSS</title>
</head>
<style>
*{
    margin: 0;
    padding: 0;
}
.rate {
    border: 1px solid #cccccc;
    float: left;
    height: 46px;
    padding: 0 10px;
}
.rate:not(:checked) > input {
    position:absolute;
    top:-9999px;
}
.rate:not(:checked) > label {
    float:right;
    width:1em;
    overflow:hidden;
    white-space:nowrap;
    cursor:pointer;
    font-size:30px;
    color:#ccc;
}
.rate:not(:checked) > label:before {
    content: '★ ';
}
.rate > input:checked ~ label {
    color: #ffc700;    
}
.rate:not(:checked) > label:hover,
.rate:not(:checked) > label:hover ~ label {
    color: #deb217;  
}
.rate > input:checked + label:hover,
.rate > input:checked + label:hover ~ label,
.rate > input:checked ~ label:hover,
.rate > input:checked ~ label:hover ~ label,
.rate > label:hover ~ input:checked ~ label {
    color: #c59b08;
}
</style>
<body>
    <div class="rate">
        <input type="radio" id="star5" name="rate" value="5" /><label for="star5" title="text">5 stars</label>
        <input type="radio" id="star4" name="rate" value="4" /><label for="star4" title="text">4 stars</label>
        <input type="radio" id="star3" name="rate" value="3" /><label for="star3" title="text">3 stars</label>
        <input type="radio" id="star2" name="rate" value="2" /><label for="star2" title="text">2 stars</label>
        <input type="radio" id="star1" name="rate" value="1" /><label for="star1" title="text">1 star</label>
    </div>
</body>

</html>

需要注意的是,您在此处引入了并发性,因此您需要确保在执行A时B执行没有任何线程问题。

答案 1 :(得分: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中启动任何你想要的操作,然后等待所有这些操作完成后,一旦它们全部“排队”。