.NET - Stop calling another async method

当我们需要在一个async方法中等待一个同步方法的时候,而不是await另外一个async方法,这个时候就需要使用到TaskCompletionSource

public class TaskCompletionSource<TResult>

官方文档如是描述:

Represents the producer side of a Task<TResult> unbound to a delegate, providing access to the consumer side through the Task property.

In many scenarios, it is useful to enable a Task<TResult> to represent an external asynchronous operation. TaskCompletionSource<TResult> is provided for this purpose. It enables the creation of a task that can be handed out to consumers. The consumers can use the members of the task the same way as they would in any other scenario handling task member variables. However, unlike most tasks, the state of a task created by a TaskCompletionSource is controlled explicitly by the methods on TaskCompletionSource. This enables the completion of the external asynchronous operation to be propagated to the underlying Task. The separation also ensures that consumers are not able to transition the state without access to the corresponding TaskCompletionSource. For more information, see the entry The Nature of TaskCompletionSource<TResult> in the Parallel Programming with .NET blog.
class Program
{
    static void Log(string msg)
    {
        var s = string.Format("[{0}] - {1}", DateTime.Now, msg);
        Console.WriteLine(s);
    }
  
    static async Task<string> ReturnAsync()
    {
        TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
        var rand = new Random();
        System.Timers.Timer tm = new System.Timers.Timer() {
            Interval = rand.Next() % 10000,
        };
        tm.Elapsed += (sender, args) => {
            tcs.SetResult(string.Format("You waited {0} ms", tm.Interval));
        };
        tm.Start();
        return await tcs.Task;
    }
  
    static void Main(string[] args)
    {
        Log("Enter program");
        Task.Run(async () => {
            var s = await ReturnAsync();
            Log(s);
        }).Wait();
        Log("End program");
    }
}

输出

[2017/6/30 15:40:36] - Enter program
[2017/6/30 15:40:44] - You waited 8108ms
[2017/6/30 15:40:44] - End program