async await与async await Task.Run

 

普通的async await方法其实是一个同步的异步调用,此方式并不开启新的线程,只是一个多任务处理模式,只是主线程在运行时不会阻塞卡死。此方式只能调用异步方法。

(使用async和await定义异步方法不会创建新线程,所以使用Thread.Sleep(3000)主线程也会阻塞卡死)

(由于不是开始新线程,所以在方法内页面的所有控件都可以直接访问)

而async await Task.Run是一个真实的异步模式,此方式实质就是开启一个新的托管的线程。并且此方式可以调用同步方法。

(使用await Task.Run定义异步方法会创建新线程,所以使用Thread.Sleep(3000)不影响主线程)

(不考虑资源消耗的情况下,使用await Task.Run貌似是个更好的选择)(当然开启新线程会消耗更多的资源)

(由于是开启新新线程,所以在await Task.Run方法体中就不可以直接调用页面内控件了)

 

    public partial class YiBuTest : Window
    {
        public YiBuTest()
        {
            InitializeComponent();
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {

        }


        private async void btnClick_Click(object sender, EventArgs e)
        {
            // 这里可以做一些不依赖回复的操作
            richTextBox1.Text += "\r\n等待服务器回复中.................\n";

            //long length = await AccessWebAsync();
            long length = await GetAwaitRunString("参数");

            richTextBox1.Text += String.Format("\n 回复成功,字节长度为:  {0}.\r\n", length);

            txbMainThreadID.Text = Thread.CurrentThread.ManagedThreadId.ToString();
        }

        #region await调用异步方法(使用async和await定义异步方法不会创建新线程,所以使用Thread.Sleep(3000)主线程也会阻塞卡死)(由于不是开始新线程,所以在方法内页面的所有控件都可以直接访问)
        // 使用C# 5.0中提供的async 和await关键字来定义异步方法
        // 从代码中可以看出C#5.0 中定义异步方法就像定义同步方法一样简单。
        // 使用async和await定义异步方法不会创建新线程,
        // 它运行在现有线程上执行多个任务.
        // 此时不知道大家有没有一个疑问的?在现有线程上(即UI线程上)运行一个耗时的操作时,
        // 为什么不会堵塞UI线程的呢?
        // 这个问题的答案就是 当编译器看到await关键字时,线程会
        private async Task<long> AccessWebAsync()
        {
            MemoryStream content = new MemoryStream();

            // 对MSDN发起一个Web请求
            HttpWebRequest webRequest = WebRequest.Create("https://docs.microsoft.com/zh-cn/") as HttpWebRequest;
            if (webRequest != null)
            {
                // 返回回复结果
                using (WebResponse response = await webRequest.GetResponseAsync())
                {
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        await responseStream.CopyToAsync(content);
                    }
                }
            }

            txbAsynMethodID.Text = Thread.CurrentThread.ManagedThreadId.ToString();

            return content.Length;
        }
        #endregion

        #region await调用同步方法await Task.Run(使用await Task.Run定义异步方法会创建新线程,所以使用Thread.Sleep(3000)不影响主线程)(不考虑资源消耗的情况下,使用await Task.Run貌似是个更好的选择)(当然开启新线程会消耗更多的资源)
        //(由于是开启新新线程,所以在await Task.Run方法体中就不可以直接调用页面内控件了)
        private async Task<long> GetAwaitRunString(string str)
        {

            var task = await Task.Run<long>(() =>
            {

                return tongbufangfa(str);

            });

            return task;
        }

        private long tongbufangfa(string str)
        {
            //线程停顿3秒    
            Thread.Sleep(3000);
            MemoryStream content = new MemoryStream();

            // 对MSDN发起一个Web请求
            HttpWebRequest webRequest = WebRequest.Create("https://docs.microsoft.com/zh-cn/") as HttpWebRequest;
            if (webRequest != null)
            {
                // 返回回复结果
                using (WebResponse response = webRequest.GetResponse())
                {
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        responseStream.CopyTo(content);
                    }
                }
            }

            return content.Length;
        }
        #endregion
    }

 

上一篇:为什么不建议直接使用 Async 注解?


下一篇:120. 三角形最小路径和