C#使任务线程前景

时间:2016-11-29 10:21:29

标签: c# multithreading task-parallel-library task threadpool

我正在使用Task通过不同的线程创建和执行某些操作,一旦操作完成,我也回调被调用。

 System.Threading.Tasks.Task.Factory.StartNew(() =>
                   this._httpService.CreateRecord(new Uri(Configuration.Current.CreateRecordUrl), httpObj)).ContinueWith(
                   (response) =>
                   {
                       if (!response.IsFaulted)
                       {
                           if (httpObj.CallBack != null)
                           {
                               httpObj.CallBack(response.Result);
                           }
                       }
                       else {
                           this._logger.Error("There was some error which causes the task to fail");


                       }
                   });

我的控制台应用程序的主要线程没有等待任务线程完成,因为它的后台线程。 如何创建任务线程前台线程

谢谢

4 个答案:

答案 0 :(得分:3)

您应该等待主线程中任务的完成。

将您的代码更改为

PROGRAM ODRPACK95_EXAMPLE
   USE ODRPACK95
   USE REAL_PRECISION
   REAL (KIND=R8), ALLOCATABLE :: BETA(:),X(:,:),Y(:,:)
   INTEGER :: NP,N,M,NQ
   INTERFACE
      SUBROUTINE FCN(N,M,NP,NQ,LDN,LDM,LDNP,BETA,XPLUSD,IFIXB,IFIXX,LDIFX,&
         IDEVAL,F,FJACB,FJACD,ISTOP)
         USE REAL_PRECISION
         INTEGER :: IDEVAL,ISTOP,LDIFX,LDM,LDN,LDNP,M,N,NP,NQ
         REAL (KIND=R8) :: BETA(NP),F(LDN,NQ),FJACB(LDN,LDNP,NQ), &
            FJACD(LDN,LDM,NQ),XPLUSD(LDN,M)
         INTEGER :: IFIXB(NP),IFIXX(LDIFX,M)
      END SUBROUTINE FCN
   END INTERFACE

   NP = 2
   N  = 4
   M  = 1
   NQ = 1
   ALLOCATE(BETA(NP),X(N,M),Y(N,NQ))
   BETA(1:2) = (/ 2.0_R8, 0.5_R8 /)

   X(1:4,1)  = (/ 0_R8, 1_R8, 2_R8, 3_R8 /)
   Y(1:4,1)  = (/ 2_R8, 5_R8, 8_R8, 11_R8 /)
   CALL ODR(FCN,N,M,NP,NQ,BETA,Y,X)
   pause
END PROGRAM ODRPACK95_EXAMPLE


SUBROUTINE FCN(N,M,NP,NQ,LDN,LDM,LDNP,BETA,XPLUSD,IFIXB,IFIXX,LDIFX,&
   IDEVAL,F,FJACB,FJACD,ISTOP)

   USE REAL_PRECISION

   INTEGER :: IDEVAL,ISTOP,LDIFX,LDM,LDN,LDNP,M,N,NP,NQ, I
   REAL (KIND=R8) :: BETA(NP),F(LDN,NQ),FJACB(LDN,LDNP,NQ), &
      FJACD(LDN,LDM,NQ),XPLUSD(LDN,M)
   INTEGER :: IFIXB(NP),IFIXX(LDIFX,M)

   ISTOP = 0

    !Calculate model.
   IF (MOD(IDEVAL,10).NE.0) THEN
      DO I=1,N
         F(I,1) = BETA(1)*XPLUSD(I,1)+BETA(2)
      END DO
   END IF

END SUBROUTINE FCN

Wait()方法有一些重载来指定等待的时间。如果由于取消异常而导致任务执行失败,您还必须添加一些异常处理。

答案 1 :(得分:3)

StartNew()方法返回FCN个实例。在返回的任务上调用Wait()方法将阻塞主线程,直到任务完成。

var task =  System.Threading.Tasks.Task.Factory.StartNew(() =>
                   this._httpService.CreateRecord(new Uri(Configuration.Current.CreateRecordUrl), httpObj)).ContinueWith(
                   (response) =>
                   {
                       if (!response.IsFaulted)
                       {
                           if (httpObj.CallBack != null)
                           {
                               httpObj.CallBack(response.Result);
                           }
                       }
                       else {
                           this._logger.Error("There was some error whcih causes the task to faild");


                       }
                   });

task.Wait();  // Wait till your Task has finished.

答案 2 :(得分:3)

  

我的控制台应用程序的主线程没有等待Task线程完成,因为它是后台线程。

您的应用程序没有等待任务,因为您没有告诉它这样做。

正如其他人已经说过的那样,使用Wait / Resultawait等待任务,具体取决于您是否处于异步上下文中。

  

如何创建任务线程前台线程。

最有可能的是你不想在第一时间这样做。 后台线程是一个在所有前台线程结束时终止的线程。线程池线程本质上是后台线程,如果你真的想要将你的任务安排到前台线程,也就是说,一个线程将保持应用程序进程活着,即使主线程完成后,您必须创建自己的TaskScheduler。那,顺便说一句,这是使用Task.Factory.StartNew的原因。如果您不需要 Task.Factory.StartNew,请转到Task.Run

答案 3 :(得分:1)

尝试创建一个新线程而不是从池中获取。例如:

Thread t = new Thread(()=> 
{
    //all your code goes here
});
t.IsBackground = false; //by default it will be foreground. so don't need this line in your case
t.Start();

这将为您创建一个前台线程,并确保该线程完成其执行。