关于async与await的一点测试
Winform

private async Task DoAsync() { Console.WriteLine("DoAsync_Befor:" + Thread.CurrentThread.ManagedThreadId); for (int i = 0; i < 10; i++) { await Task.Run(() => { //Thread.Sleep(100); Console.WriteLine("in:" + Thread.CurrentThread.ManagedThreadId); }); Console.WriteLine("DoAsync_After:" + Thread.CurrentThread.ManagedThreadId); } } private void button2_Click(object sender, EventArgs e) { Console.WriteLine("button2_Click_befor:" + Thread.CurrentThread.ManagedThreadId); DoAsync(); Console.WriteLine("button2_Click_after:" + Thread.CurrentThread.ManagedThreadId); //Console.Read(); }
Console

static void Main(string[] args) { Console.WriteLine("Main_befor:" + Thread.CurrentThread.ManagedThreadId); DoAsync(); Console.WriteLine("Main_after:" + Thread.CurrentThread.ManagedThreadId); Console.Read(); } private static async Task DoAsync() { Console.WriteLine("DoAsync_Befor:" + Thread.CurrentThread.ManagedThreadId); for (int i = 0; i < 10; i++) { await Task.Run(() => { Thread.Sleep(100); Console.WriteLine("in:" + Thread.CurrentThread.ManagedThreadId); }); Console.WriteLine("DoAsync_After:" + Thread.CurrentThread.ManagedThreadId); } }
Winform 的DoAsync_After 始终是1,即 UI线程
而Console输出有多个情况,即Task.Run(...)中使用的线程,
所以在Winform中async与await是做特定处理的
//=========================测试代码2==========================

private async void Form1_Load(object sender, EventArgs e) { try { Console.WriteLine($"Load Begin {Thread.CurrentThread.ManagedThreadId}"); var r= AddAsync(4, 5); // var r = await AddAsync(4, 5); Console.WriteLine(r); Console.WriteLine("Load Complated"); } catch (Exception ex) { Console.WriteLine(ex.Message + Thread.CurrentThread.ManagedThreadId); } } private async Task<int> AddAsync(int a,int b) { //Thread.Sleep(1000); Console.WriteLine($"Call AddAsync Begin {Thread.CurrentThread.ManagedThreadId}"); Func<int> fac = () => { Thread.Sleep(1000); Console.WriteLine($"In Call AddAsync {Thread.CurrentThread.ManagedThreadId}"); return a + b; }; Console.WriteLine($"Call AddAsync End {Thread.CurrentThread.ManagedThreadId}"); return await Task.Run<int>(fac); }
调整为
// var r= AddAsync(4, 5);
var r = await AddAsync(4, 5);
后的输出是
官方Demo

public partial class MainWindow : Window { // Mark the event handler with async so you can use await in it. private async void StartButton_Click(object sender, RoutedEventArgs e) { // Call and await separately. //Task<int> getLengthTask = AccessTheWebAsync(); //// You can do independent work here. //int contentLength = await getLengthTask; int contentLength = await AccessTheWebAsync(); resultsTextBox.Text += String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength); } // Three things to note in the signature: // - The method has an async modifier. // - The return type is Task or Task<T>. (See "Return Types" section.) // Here, it is Task<int> because the return statement returns an integer. // - The method name ends in "Async." async Task<int> AccessTheWebAsync() { // You need to add a reference to System.Net.Http to declare client. HttpClient client = new HttpClient(); // GetStringAsync returns a Task<string>. That means that when you await the // task you'll get a string (urlContents). Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); // You can do work here that doesn't rely on the string from GetStringAsync. DoIndependentWork(); // The await operator suspends AccessTheWebAsync. // - AccessTheWebAsync can't continue until getStringTask is complete. // - Meanwhile, control returns to the caller of AccessTheWebAsync. // - Control resumes here when getStringTask is complete. // - The await operator then retrieves the string result from getStringTask. string urlContents = await getStringTask; // The return statement specifies an integer result. // Any methods that are awaiting AccessTheWebAsync retrieve the length value. return urlContents.Length; } void DoIndependentWork() { resultsTextBox.Text += "Working . . . . . . .\r\n"; } }
注意Demo中可以用2种方式调用AccessTheWebAsync,即同步调用(带await)与 异步调用
--------------------------------以下写法会导致UI卡死 ------------------------------

private async void Form1_Load(object sender, EventArgs e) { try { Console.WriteLine($"Load Begin {Thread.CurrentThread.ManagedThreadId}"); var r= AddAsync(4, 5); //var r = await AddAsync(4, 5); //Console.WriteLine(r); Console.WriteLine(r.Result); Console.WriteLine("Load Complated"); } catch (Exception ex) { Console.WriteLine(ex.Message + Thread.CurrentThread.ManagedThreadId); } } private async Task<int> AddAsync(int a,int b) { //Thread.Sleep(1000); Console.WriteLine($"Call AddAsync Begin {Thread.CurrentThread.ManagedThreadId}"); Func<int> fac = () => { Thread.Sleep(1000); Console.WriteLine($"In Call AddAsync {Thread.CurrentThread.ManagedThreadId}"); return a + b; }; Console.WriteLine($"Call AddAsync End {Thread.CurrentThread.ManagedThreadId}"); //var t= Task.Run<int>(fac); //return t.Result; return await Task.Run<int>(fac); }
需要改成这样

while (!r.IsCompleted) { Application.DoEvents(); Thread.Sleep(100); } Console.WriteLine(r.Result);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
2017-02-28 matlab柱面图
2012-02-28 NHiberante3.2 调用存储过程之Errors in named queries: