Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 任务与线程的差异_C#_.net_Multithreading_Task - Fatal编程技术网

C# 任务与线程的差异

C# 任务与线程的差异,c#,.net,multithreading,task,C#,.net,Multithreading,Task,我不熟悉并行编程。NET中有两个可用的类:Task和Thread 因此,我的问题是: 这些课程之间有什么区别 什么时候使用线程优于任务(反之亦然) 线程是一个较低级别的概念:如果您直接启动一个线程,您知道它将是一个单独的线程,而不是在线程池中执行等 Task不仅仅是“在哪里运行代码”的抽象,它实际上只是“对未来结果的承诺”。例如一些不同的例子: 任务。延迟不需要任何实际的CPU时间;这就像在将来设置一个计时器 WebClient.downloadstringtasksync返回的任务不会在本

我不熟悉并行编程。NET中有两个可用的类:
Task
Thread

因此,我的问题是:

  • 这些课程之间有什么区别
  • 什么时候使用
    线程
    优于
    任务
    (反之亦然)

线程
是一个较低级别的概念:如果您直接启动一个线程,您知道它将是一个单独的线程,而不是在线程池中执行等

Task
不仅仅是“在哪里运行代码”的抽象,它实际上只是“对未来结果的承诺”。例如一些不同的例子:

  • 任务。延迟
    不需要任何实际的CPU时间;这就像在将来设置一个计时器
  • WebClient.downloadstringtasksync
    返回的任务不会在本地占用太多CPU时间;它代表的结果可能会将大部分时间花在网络延迟或远程工作(在web服务器上)
  • task.Run()
    返回的任务实际上是说“我希望您单独执行此代码”;代码执行的确切线程取决于许多因素
注意,
任务
抽象对于C#5中的异步支持至关重要

一般来说,我建议您尽可能使用更高级别的抽象:在现代C代码中,您应该很少需要显式地启动自己的线程。

通常您会听到任务是比线程更高级别的概念。。。这就是这个短语的意思:

  • 您不能使用Abort/ThreadAbortedException,您应该支持 定期测试
    令牌.IsCancellationRequested
    标志时,“业务代码”中的cancel事件(还应避免长时间或无时间连接,例如连接到db,否则您将永远没有机会测试此标志)。出于类似的原因,
    Thread.Sleep(delay)
    call应替换为
    Task.delay(delay,token)
    call(将令牌传递到内部以有可能中断延迟)

  • 对于任务,没有线程的
    Suspend
    Resume
    方法功能任务实例也不能重用

  • 但你会得到两个新工具:

    a) 续集

    // continuation with ContinueWhenAll - execute the delegate, when ALL
    // tasks[] had been finished; other option is ContinueWhenAny
    
    Task.Factory.ContinueWhenAll( 
       tasks,
       () => {
           int answer = tasks[0].Result + tasks[1].Result;
           Console.WriteLine("The answer is {0}", answer);
       }
    );
    
    b) 嵌套/子任务

    //StartNew - starts task immediately, parent ends whith child
    var parent = Task.Factory.StartNew
    (() => {
              var child = Task.Factory.StartNew(() =>
             {
             //...
             });
          },  
          TaskCreationOptions.AttachedToParent
    );
    
  • 所以系统线程对任务是完全隐藏的,但任务的代码仍然在具体的系统线程中执行系统线程是任务的资源,当然,在任务并行执行的框架下仍然有线程池。线程如何执行新任务可能有不同的策略。另一个共享资源TaskScheduler关心它。TaskScheduler解决的一些问题1)更喜欢在同一线程中执行任务及其conitnuation最小化切换成本-也称为内联执行)2)更喜欢按启动顺序执行任务-也称为公平性3)更有效地在非活动线程之间分配任务,具体取决于“任务活动的先验知识”-又名工作窃取。重要提示:一般来说,“异步”与“并行”不同。使用TaskScheduler选项可以设置异步任务在一个线程中同步执行。要表示并行代码执行,可以使用更高的抽象(比任务高):、

  • 任务与C#async/await特性集成,也称为承诺模型,例如那里
    requestButton.Clicked+=async(o,e)=>processresponse(await client.RequestAsync(e.ResourceName))
    client.RequestAsync的执行将不会阻止UI线程。重要提示:在后台,单击的
    委托调用是绝对正常的(所有线程都由编译器完成)

  • 这就足够做出选择了。如果您需要支持调用倾向于挂起的遗留API的取消功能(例如,无超时连接),并且在这种情况下支持Thread.Abort(),或者如果您正在创建多线程后台计算,并且希望使用Suspend/Resume优化线程之间的切换,这意味着手动管理并行执行-使用Thread。否则,请转到Tasks,因为它们将使您可以轻松地对多组任务进行操作,并集成到该语言中,使开发人员更具生产力active-。

    该类用于在Windows中创建和操作

    表示某个异步操作,是用于异步并行运行任务的一组API的一部分

    在过去的日子里(即在TPL之前),使用
    线程
    类是在后台或并行运行代码的标准方法之一(更好的选择通常是使用但是,这很麻烦,并且有几个缺点,其中最重要的是在后台创建一个全新线程来执行任务的性能开销


    现在使用任务和TPL在90%的时间里是一个更好的解决方案,因为它提供了抽象,允许更有效地使用系统资源。我想有一些情况下,您希望对运行代码的线程进行显式控制,但是一般来说,如果您想运行异步的东西您的第一个调用端口应该是TPL。

    Read.Preference任务,除非您需要线程。线程需要资源(1MB堆栈(在.net Committed中)、线程内核对象等).Task也作为单独的线程并行运行,但它是一个系统线程池线程,由系统考虑cpu核等进行优化,用于跨系统运行许多任务。除此之外,任务完成后可以返回一个对象,因此有一种方便的方法可以知道并行执行的结果。@AbhijitKadam Wh你说的是“系统”,你指的是.NET框架吗?这是一个有趣的问题