你想象中的Task后续,很简单?

【导读】前不久,写过一篇关于Task的简短文章,通过评论和转载得到好评,刚好我昨晚又写了一篇实现简单的消息队列也提到了Task,难道不应该是看具体执行什么操作,再考虑最佳方案?本文我们再次通过简短内容谈谈Task

在评论中我提到,Task默认在线程池中运行,若执行耗时操作,此时极容易造成线程阻塞,最终导致线程池激增,很显然这是不正确的做法

然鹅,有的童鞋说了,给Task配置TaskCreationOptions.LongRunning即可解决耗时问题,此时将创建线程而非在线程池运行,要是执行耗时操作且无需知道返回结果(见上一篇),那干嘛不直接用Thread呢?

TaskCreationOptions.LongRunning直接创建线程,所以本文我们重点来讲讲该选项的正确使用方式,知其然,知其所以然。

再谈Task创建线程

我们一直在强调配置Task选项即可创建非线程池线程,那么我们是否可以通过一个简单例子来进行一次论证呢?如下代码和图展足以胜前言,至于细节,只能自行研究源码得知

证明:TaskCreationOptions.LongRunning创建非线程池线程

public static Format _colorify { get; set; }
static void Main(string[] args)
{
    _colorify = new Format(Theme.Light);

    int workerThreads, completionPortThreads;

    ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
    _colorify.WriteLine(workerThreads.ToString(), Colors.bgDefault);
    _colorify.WriteLine(completionPortThreads.ToString(), Colors.bgDefault);

    ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
    _colorify.WriteLine(workerThreads.ToString(), Colors.bgDefault);
    _colorify.WriteLine(completionPortThreads.ToString(), Colors.bgDefault);

    _colorify.WriteLine("---------------------------", Colors.bgSuccess);

    Task.Factory.StartNew(() =>
    {
      ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
      _colorify.WriteLine(workerThreads.ToString(), Colors.bgWarning);
      _colorify.WriteLine(completionPortThreads.ToString(), Colors.bgWarning);

      ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
      _colorify.WriteLine(workerThreads.ToString(), Colors.bgWarning);
      _colorify.WriteLine(completionPortThreads.ToString(), Colors.bgWarning);

    }, TaskCreationOptions.LongRunning);

    Console.Read();
}

同样,反其道行之,将LongRunning选项配置去除,则如下橙色部分所展示的线程池工作线程将减少1即(32766)

Task配置LongRunning是否可用于异步呢?

针对此问题的答案,如果我们不能立马给出答案,那么说明我们对异步还没有充分的理解,这里给出我对异步浅薄的定义:添加必要的逻辑(状态机),以允许释放当前线程,若长时间运行的异步操作已完成,则将结果返回到同一线程中,换言之,异步仅用于I/O操作。

我们来看如下一个例子

static async Task Main(string[] args)
{
    await AsyncTaskFactoryNew();

    Console.Read();
}

static async Task AsyncTaskFactoryNew()
{
    await Task.Factory.StartNew(() => {
      // do your logic
    });
}


通过上述我们对异步的定义,然后再来看上述例子,结果显而易见,因为用了异步后将释放当前线程,也就是在第一次await后,通过Task选项所配置的创建非线程池线程将会被销毁,所以给Task配置创建非线程池线程结合使用异步相互矛盾,故毫无意义。

几篇简短内容,仍只是冰山一角,其中所涉及内容仍有许多供我们好好研究,比如如何利用Task实现断点续传中的暂停、取消呢?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值