class Program { static void Main(string[] args) { var result = DownloadStringWithTimeout("http://www.yueyangdujia.com"); Console.WriteLine("异步方法执行中"); for (int i = 0; i < 3; i++) { System.Threading.Thread.Sleep(1000); Console.WriteLine("休息了"+(i+1)+"秒"); } var str= result.Result; //这里使用到异步方法的返回值,需要等待异步方法执行完毕。 Console.WriteLine("异步方法执行后,同步执行以下代码"); Console.WriteLine(str); Console.Read(); } static async Task<string> DownloadStringWithTimeout(string uri) { using (var client=new HttpClient()) { var downloadTask = client.GetStringAsync(uri); var timeoutTask = Task.Delay(3000); var completedTask = await Task.WhenAny(downloadTask, timeoutTask); if (completedTask == timeoutTask) { System.Threading.Thread.Sleep(2000); Console.WriteLine("异步方法执行完成"); return null; } System.Threading.Thread.Sleep(2000); Console.WriteLine("异步方法执行完成"); return await downloadTask; } } }
执行顺序如 Console.WriteLine显示一样。DownloadStringWithTimeout和下面的代码一起执行,大概在2秒的时候执行完毕。var str= result.Result;调用异步方法返回值的时候会等候异步方法执行。
下来去掉一些代码如下:
class Program { static void Main(string[] args) { var result = DownloadStringWithTimeout("http://www.yueyangdujia.com"); var str= result.Result; //这里使用到异步方法的返回值,需要等待异步方法执行完毕。 Console.WriteLine(str); Console.Read(); } static async Task<string> DownloadStringWithTimeout(string uri) { using (var client=new HttpClient()) { var downloadTask = client.GetStringAsync(uri); var timeoutTask = Task.Delay(3000); var completedTask = await Task.WhenAny(downloadTask, timeoutTask); if (completedTask == timeoutTask) { return null; } return await downloadTask; } } }
WhenAny接受两个异步方法参数返回先执行完成的方法。以上可以调整Task.Delay的参数。如果足够小则返回NULL。
还有一个WhenAll方法会等所有方法都执行完毕后再一起返回,代码如下。
static async Task<string> Down() { Task<string> tast1 = DownloadStringWithTimeout("http://www.yueyangdujia.com"); Task<string> tast2 = DownloadStringWithTimeout("http://www.yueyangdujia.com"); Task<string> tast3 = DownloadStringWithTimeout("http://www.yueyangdujia.com"); string[] arr = await Task.WhenAll(tast3, tast2, tast1); return String.Concat(arr); }