zoukankan      html  css  js  c++  java
  • .Net 线程&异步

    引子

    今天遇到一个简单的问题,一个获取下载文件的接口,本来是要在判断文件不存在的情况下重新生成的,但是因为重新生成需要的时间比较长,因此就考虑,当文件不存在的时候开启一个后台线程,而直接返回错误,让重试,这样体验会好一点。

    代码如下

    string filePath = "";
    if (File.Exists(filePath)) return true;
    Task.Run(() =>
    {
        // 执行生成文件的操作
    });
    return false;

    这里的Task.Run()就是启动一个后台线程,不会影响主线程,而直接返回失败,这样在用户下一次在点击下载的时候,就可以直接获取到文件了。

    开启异步线程(不阻塞线程)的方法

    1.使用Thread类

    2.使用ThreadPool线程池

    3.使用最新的Task

    第一种方法已经淘汰,因为这种方法是不会考虑机器的实际情况,会不停的创建线程,最终很容易导致内容溢出;

    第二种方法,在Task没有出现的时候经常使用,优点是线程池中会合理管理线程,如果到达上限后,后续创建的线程会进行排队,但是用它来操作线程略显麻烦

    第三种是新方法,比较推荐,改善了方法1和2的缺点。

    使用方法如下

    Task t1 = new Task(()=>{});
    t1.Start();

    或者

    Task.Run(()=> { });

    后者相当于将创建的线程直接启动了。

    后续执行ContinueWith

    可以对后台任务分成若干块,除了第一部分外,以ContinueWith连接,如下

     Task.Run(()=> { }).ContinueWith((t)=> { }).ContinueWith((t) => { });

    而参数t就是上一步执行的task,可以在ContinueWith方法对上一步的操作结果进行判断,以进行不同的处理

    Task的

    IsCompleted属性可以判断任务是否执行完成

    IsCompletedSuccessfully属性可以判断任务是否有异常

    可以放在ContinueWith中用来判断任务的执行情况

    线程同步

    Task对象使用Wait()方法来实现线程的等待,多个Task则可以使用Task.WaitAll()或者Task.WaitAny()来同步

    wait()和await

    为了线程同步有时候需要对线程进行等待,有两种方法,如

    Task.Run(()=>{}).Wait()

    或者

    await Task.Run(()=>{})

    这两种方法效果类似,都是将线程等待起来,有结果再继续,但是区别在于wait()是同步阻塞,而await是异步阻塞。

    也就是说wait()的时候,线程是占用状态,无法释放

    而await的时候,线程是释放的,可以用来做其他的工作

    一个现象

    经常发现一些朋友在写web项目代码的时候,方法中调用了很多await的异步接口,其实这些异步接口的使用并不能提高程序的性能,也就是说不是说一个接口使用同步接口调用了3秒,换成异步接口就变1秒了(去掉await并行执行另说)。

    执行效率还是不会变的,只不过程序在遇到await之后将线程释放,以提高网站的吞吐量。

    总结

    异步和多线程真的相当复杂,这里只是记录了自己使用中的一些经验,肯定有不足和错误的地方,希望见谅

    总之在使用异步和多线程的时候,要比单线程程序更加复杂,一些单线程程序中理所应当的东西,放在多线程异步环境下可能会出现大问题,使用的时候必须要小心和谨慎

  • 相关阅读:
    Android游戏开发22:Android动画的实现J2me游戏类库用于Android开发
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第三部分,完整代码)
    使用OGR创建dxf格式矢量数据
    mysql 数据库引擎 MyISAM InnoDB 大比拼 区别
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第二部分)
    mysql 更改数据库引擎
    android sqlite SQLiteDatabase 操作大全 不看后悔!必收藏!看后精通SQLITE (第一部分)
    android 数字键盘使用
    MySQL Innodb数据库性能实践
    eclipse : Error while performing database login with the driver null
  • 原文地址:https://www.cnblogs.com/gamov/p/13215112.html
Copyright © 2011-2022 走看看