我是否需要使用异步和等待来标记流中的所有方法

时间:2018-02-06 15:36:05

标签: c# async-await

我有一个调用多个私有方法的公共方法。我是否必须使用异步和等待标记流中的所有方法,或者仅使用耗时工作的方法?

1 个答案:

答案 0 :(得分:0)

不,您不必将所有过程标记为异步,只需将您调用其他异步函数的过程标记为异步。您可能在调用.NET函数时已经这样做了

async Task DoIt(...)
{
     // call async function, wait until finished
     string txt = await ReadMyTextFile();

     // call non-async function
     string reversed = txt.Reverse();

     // call async function, wait until finished
     await WriteMyTextFile(reversed);
} 

如果你调用异步函数,你可以放心,在这个函数的某个地方有一个等待。事实上,如果您忘记等待程序中的某个地方,您的编译器会发出警告。

如果正在执行该过程的线程满足await,则线程不会等待,直到等待的任务完成,但是上升到其调用堆栈以查看该过程的调用者是否在等待,并且继续处理该程序直到等待。再次上调调用堆栈,继续处理直到等待等等。

Task<int> ReadNumber(FileStream in
{
    // start fetching data from a database, don't await yet
    Task<int> taskFetchCustomerCount = FetchCustomerCountAsync();

    // once the await is met in FetchCustomerCountAsync, the thread will start doing this
    // also don't need the result yet. Don't await
    Task<MonthlyReport> taskReadReport = ReadMonthlyReportAsync();

    // once the await is met in ReadMonthlyReportAsync the thread will continue doing this
    // this is a non-async function
    string reportPeriod = GetReportPeriod();

    // by now, we need the result from the database. Start waiting for it
    int customerCount = await taskFetchCustomerCount;

    // if the database is not finished yet, the thread goes up the call stack to see 
    // if the caller can continue

    // after a while the database has fetched the result, we can continue
    string customerCountLine = 
        $"At the end of {reportPeriod} the company had {customerCount} customers.";

    // now we need the result from the Report reading:
    MonthlyReport report = await taskReadReport;

    // call a non-async function
    report.SetCustomerCountLine(customerCountLine);

    // save the report. Nothing to do anymore, so await until saving completed
    await report.SaveAsync();
}