遗忘海岸

江湖程序员 -Feiph(LM战士)

导航

关于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();

        }
View Code

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);
            }
        }
View Code

 

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);
          
        }
View Code

调整为

// 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";
        }
    }
View Code

注意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);
            
          
        }
View Code

 需要改成这样

                while (!r.IsCompleted)
                {
                    Application.DoEvents();
                    Thread.Sleep(100);
                }
                Console.WriteLine(r.Result);
View Code

 

posted on 2022-02-28 16:28  遗忘海岸  阅读(56)  评论(0编辑  收藏  举报