C# Aysc Await 实现异步编程

来源:互联网 发布:火影忍者手游cdkey淘宝 编辑:程序博客网 时间:2024/05/16 05:39
废话少说,直接上代码
  public MainWindow()        {            InitializeComponent();        }        private async void startButton_Click(object sender, RoutedEventArgs e)        {            resultsTextBox.Clear();            await CreateMultipleTasksAsync();            resultsTextBox.Text += "\r\n\r\nControl returned to startButton_Click.\r\n";        }        private async Task CreateMultipleTasksAsync()        {            // Declare an HttpClient object.            HttpClient client = new HttpClient();            // Create and start the tasks. As each task finishes, DisplayResults             // displays its length.            Task<int> download1 =                 ProcessURL("http://msdn.microsoft.com", client);            Task<int> download2 =                 ProcessURL("http://msdn.microsoft.com/en-us/library/hh156528(VS.110).aspx", client);            Task<int> download3 =                 ProcessURL("http://msdn.microsoft.com/en-us/library/67w7t67f.aspx", client);            // Await each task.            int length1 = await download1;            int length2 = await download2;            int length3 = await download3;            int total = length1 + length2 + length3;                        // Display the total count for the downloaded websites.            resultsTextBox.Text +=                string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);        }        async Task<int> ProcessURL(string url, HttpClient client)        {            var byteArray = await client.GetByteArrayAsync(url);            DisplayResults(url, byteArray);            return byteArray.Length;        }                private void DisplayResults(string url, byte[] content)        {            // Display the length of each website. The string format             // is designed to be used with a monospaced font, such as            // Lucida Console or Global Monospace.            var bytes = content.Length;            // Strip off the "http://".            var displayURL = url.Replace("http://", "");            resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);        }

界面上只有一个button和textbox,按下button后 程序将先进入“CreateMultipleTasksAsync”,然后再进入“ProcessURL”,大家知道打开网页是需要时间的如果此时线程一直等待网页的返回一定会有短暂的卡顿(线程阻塞),如果在方法前加了“async”即开始了异步方法,当调用await 唤醒(期间线程是空闲的,你点鼠标什么的也会有响应),此时线程继续执行方法。

关于await 微软官方的解释是:

await 运算符在异步方法应用于任务,以挂起执行方法,直到所等待的任务完成。 这个任务表示正在进行的工作。

在其中使用 await 的异步方法必须通过async 关键字进行修改。使用 async 修饰符定义并且通常包含一个或多个await 表达式的这类方法称为异步方法

应用 await 运算符的任务通常是实现基于任务的异步模式的方法调用的返回值。示例包括 Task 或 Task<TResult> 类型的值。在以下代码中,HttpClient 方法 GetByteArrayAsync 返回 Task<byte[]> (getContentsTask)。当任务完成时,任务约定生成实际字节数组。 await 运算符应用于 getContentsTask 以在 SumPageSizesAsync 中挂起执行,直到 getContentsTask 完成。同时,控制权会返回给 SumPageSizesAsync 的调用方。当 getContentsTask 完成之后,await 表达式计算为字节数组。C#private async Task SumPageSizesAsync(){    // To use the HttpClient type in desktop apps, you must include a using directive and add a     // reference for the System.Net.Http namespace.    HttpClient client = new HttpClient();    // . . .    Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);    byte[] urlContents = await getContentsTask;    // Equivalently, now that you see how it works, you can write the same thing in a single line.    //byte[] urlContents = await client.GetByteArrayAsync(url);    // . . .}System_CAPS_important重要事项 有关完整示例,请参阅演练:使用 Async 和 Await 访问 Web(C# 和 Visual Basic)。可以从 Microsoft 网站上的开发人员代码示例下载该示例。该示例处于 AsyncWalkthrough_HttpClient 项目中。 如前面的示例中所示,如果 await 应用于返回 Task<TResult> 的方法调用结果,则 await 表达式的类型为 TResult。如果 await 应用于返回 Task 的方法调用结果,则 await 表达式的类型为 void。以下示例演示了差异。C#// Keyword await used with a method that returns a Task<TResult>.TResult result = await AsyncMethodThatReturnsTaskTResult();// Keyword await used with a method that returns a Task.await AsyncMethodThatReturnsTask();await 表达式不阻止正在执行它的线程。而是使编译器将剩下的异步方法注册为等待任务的延续任务。控制权随后会返回给异步方法的调用方。任务完成时,它会调用其延续任务,异步方法的执行会在暂停的位置处恢复。await 表达式只能在由 async 修饰符标记的立即封闭方法体、lambda 表达式或异步方法中出现。术语“await”在该上下文中仅用作关键字。在其他位置,它会解释为标识符。在方法、lambda 表达式或匿名方法中,await 表达式不能在同步函数体、查询表达式、lock 语句块或不安全上下文中出现。异常大多数异步方法返回 Task 或 Task<TResult>。返回任务的属性携带有关其状态和历史记录的信息,如任务是否完成、异步方法是否导致异常或已取消以及最终结果是什么。 await 运算符可访问这些属性。如果等待的任务返回异步方法导致异常,则 await 运算符会重新引发异常。如果等待的任务返回异步方法取消,则 await 运算符会重新引发 OperationCanceledException。处于故障状态的单个任务可以反映多个异常。例如,任务可能是对 Task.WhenAll 调用的结果。等待此类任务时,等待操作仅重新引发异常之一。但是,无法预测重新引发的异常。有关异步方法中的错误处理的示例,请参阅 try-catch(C# 参考)。下面的 Windows 窗体示例阐释如何在异步方法 WaitAsynchronouslyAsync 中使用 await。将该方法的行为与 WaitSynchronously 的行为进行对比。如果未向任务应用 await 运算符,WaitSynchronously 就会同步运行,而不管其定义中是否使用了 async 修饰符和在主体中是否调用了 Thread.Sleep。C#private async void button1_Click(object sender, EventArgs e){    // Call the method that runs asynchronously.    string result = await WaitAsynchronouslyAsync();    // Call the method that runs synchronously.    //string result = await WaitSynchronously ();    // Display the result.    textBox1.Text += result;}// The following method runs asynchronously. The UI thread is not// blocked during the delay. You can move or resize the Form1 window // while Task.Delay is running.public async Task<string> WaitAsynchronouslyAsync(){    await Task.Delay(10000);    return "Finished";}// The following method runs synchronously, despite the use of async.// You cannot move or resize the Form1 window while Thread.Sleep// is running because the UI thread is blocked.public async Task<string> WaitSynchronously(){    // Add a using directive for System.Threading.    Thread.Sleep(10000);    return "Finished";}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀孕第一个月打针了怎么办 唐氏筛查神经管缺陷高风险怎么办 门诊处方笺丢了怎么办 孕中期睡觉手麻怎么办 怀孕2个月了没胎心胎芽怎么办 怀孕腿疼的厉害怎么办 孕妇老是失眠多梦怎么办 孕妇会失眠多梦怎么办 怀孕5个月睡不着怎么办 6个月孕妇失眠怎么办 彩超脉络丛囊肿怎么办 双侧脉络丛囊肿怎么办 唐筛神经管缺陷高风险怎么办 雌激素低怎么办吃什么东西补 我怀了狗的孩子怎么办 结婚2年不要孩子怎么办 备孕一直没怀孕怎么办 刚生的婴儿打嗝怎么办 小孩40天黄疸高怎么办 婴儿身高长得慢怎么办 四个月的宝宝哭怎么办 孕39周羊水偏多怎么办 孕39周羊水浑浊怎么办 孕晚期羊水过少怎么办 怀孕脐带绕颈一周怎么办 nt检查宝宝趴着怎么办 四维胎儿有问题怎么办 怀孕70天没有胎心怎么办 怀孕20天不想要怎么办 换轮胎胎压监测怎么办 怀孕了吐的厉害该怎么办 怀孕吐完嗓子疼怎么办 怀孕16周不想要怎么办 怀孕四个月胎盘低置怎么办 孕37周胎盘三级怎么办 孕37周胎盘老化怎么办 怀孕22周胎盘1级怎么办 婴儿吃奶粉吐奶怎么办 宝宝吐奶又拉稀怎么办 羊水穿刺21三体怎么办 开始长妊娠纹了怎么办