zoukankan      html  css  js  c++  java
  • TPL详解、使用

    使用时注意点

     1 private async void button5_Click(object sender, EventArgs e)
     2         {
     3             /*
     4             string i1 = await F1Async();
     5             MessageBox.Show("i1=" + i1);
     6             string i2 = await F2Async();
     7             MessageBox.Show("i2=" + i2);
     8             */
     9             Task<string> task1 = F1Async();
    10             Task<string> task2 = F2Async();
    11             string i1 = await task1;
    12             MessageBox.Show("i1=" + i1);
    13             string i2 = await task2;
    14             MessageBox.Show("i2=" + i2);
    15         }
    16 
    17         static Task<string> F1Async()
    18         {
    19             MessageBox.Show("F1 Start");
    20             return Task.Run(() => {
    21                 System.Threading.Thread.Sleep(1000);
    22                 MessageBox.Show("F1 Run");
    23                 return "F1";
    24             });
    25         }
    26 
    27         static Task<string> F2Async()
    28         {
    29             MessageBox.Show("F2 Start");
    30             return Task.Run(() => {
    31                 System.Threading.Thread.Sleep(2000);
    32                 MessageBox.Show("F2 Run");
    33                 return "F2";
    34             });
    35         }

    如上两个异步方法,在调用时,第一种调用提示框会按步骤弹出,而第二种则混乱的弹出,但这也不难理解因为多线程本来就是分片执行不按代码顺序;

    第二种写法的await是作为一个最后的保险作用,它的意义在于如果开始就执行了ok,如果没执行则这步该执行了

    不能使用async修饰而要调用异步方法怎么办?

      出现这种情况比较少,此时可以获得Task<T>类型的返回值,获取Task<T>.Result()方法,终止异步;

      但请注意尽量少的使用Result()方法,他会造成数据上下文的死锁问题。

    如果返回值就是一个立即可以随手可得的值,那么就用 Task.FromResult();

    异步方法的风格转换

    Task.Factory.FromAsync()把 IAsyncResult 转换为 Task,这样 APM 风格的 api 也可以用 await 来调用

    await修饰与并发执行的顺序

    被await修饰的异步方法,一定会按照顺序执行并结束,所以如果没有顺序要求可以不使用await修饰并发任务

    eg

     1 private async void button1_Click(object sender, EventArgs e)
     2 {
     3 HttpClient hc = new HttpClient();
     4 var task1 = hc.GetStringAsync(textBox1.Text);
     5 var task2 = hc.GetStringAsync(textBox2.Text);
     6 var task3 = hc.GetStringAsync(textBox3.Text);
     7 Task.WaitAll(task1, task2, task3);
     8 label1.Text = task1.Result.Length.ToString();
     9 label2.Text = task2.Result.Length.ToString();
    10 label3.Text = task3.Result.Length.ToString();
    11 }
    View Code

    在接口中使用await

    在接口定义是不能给接口做await修饰,然而为了增加可读性,在方法明后添加async的特殊表示,在实现类中去添加await修饰即可

    异常处理

    TPL中,如果程序中出现异常,除非进行try...catch,否则有可能是感觉不到出了异常....

    TPL中有时会抛出AggregateException可以同时catch住多个异常,这通常发生在并行多个任务的情况下

    TPL与asp.net mvc

        1.  返回值改为Task<ActionResult>即可,如果方法标记为async,连自己创建Task都省了

    1 public async Task<ActionResult> Index()
    2 {
    3 return View();
    4 }
    View Code

        2.  为什么asp.net中用mvc能提升系统性能?

          准确来讲,不是提升性能,不会提高访问速度,而是提升服务器的“吞吐量”,也就是可以处理的并发请求数

    TPL常见的误区

    1.   如果用了异步,那么就要async到底;async具有传染性;
    2.   如果在使用异步api中掺杂了同步方法,则会打断异步方法,有可能造成数据死锁而且还会降低系统性能,so,不要轻易使用Wait、WaitAll
    3.   只要await、WhenAll不要task.Result、Wait、WaitAll

      

      

  • 相关阅读:
    解决在Apple Silicon (M1)安装php MongoDB扩展失败
    dyld: Library not loaded: /usr/local/opt/libpng/lib/libpng16.16.dylib
    docker自建bitwarden_rs服务器更新支持send功能
    centos安装puppeteer遇到的报错及解决方案
    Centos宝塔安装NextCloud
    苹果设备型号代码(更新至iPhone12)
    electron内使用vue-slider-component组件报“$attrs is readonly”错误
    ZSH隐藏命令行前面的用户名和主机名
    Android9.0配置charles的https抓包
    记一次discuz修改首页图片路径问题
  • 原文地址:https://www.cnblogs.com/cuijl/p/7675226.html
Copyright © 2011-2022 走看看