2013年4月12日 星期五

[C#] Task


BY JB

一、Task without return value
二、Task with return value
三、How to cancel a Task ?
四、TaskFactory
五、Reference

一、Task without return value
l   First implement a function returning nothing
/// <summary>
///
Task要做的事
/// </summary>
///
<param name="x"></param>
private void taskJob(int x)
{
      double _sum = 0;
      try
     
{
          for (int i = 0; i < x; i++)
          {
               Console.WriteLine(i.ToString());
               _sum += i;
          }
          Console.WriteLine( "
總值為={0}", _sum.ToString());
          return;
         }
         catch (Exception)
          {
             throw;
          }
     }

l   Define a Task and add the function as a parameter
// 宣告Task 並指定ActionTask
Task _task = new Task(
 () => taskJob(100)
);

l   Run it!
_task.Start();
l   Output result :

97
98
99
總值為=4950

二、Task with return value
l   First implement a function returning something
/// <summary>
///
Task要做的事
/// </summary>
///
<param name="x"></param>
private double taskJob(int x)
{

 
double _sum = 0;
  try
 
{
      for (int i = 0; i < x; i++)
      {
          Console.WriteLine(i.ToString());
          _sum += i;
       }
       return _sum;
    }
    catch (Exception)
    {
      throw;
    }
}

l   Define a Task and add the function as a parameter
// 宣告Task 並指定可Return值的Func Task
Task<double> _task = new Task<double>(
 () => taskJob(100)
);

l   Run it!
//開始執行Task
_task.Start();

l   Get the result from the Task
//取得Task Return 結果
double _rslt = _task.Result;
Console.WriteLine("
總值={0}", _rslt.ToString());

l   Output result :

97
98
99
總值=4950

三、How to cancel a Task ?

l   Use CancellationTokenSource and check IsCancellationRequested during the working of thread.

                             i.                Define a CancellationTokenSource object.
// System.Threading.CancellationToken 發出訊號,表示應該將它取消。
CancellationTokenSource cts = new CancellationTokenSource();

///
定義Token.Register,表示CancellationToken取消時會呼叫的委派
cts.Token.Register(() =>
 {

   
Console.WriteLine("中途結束Task!");
 });


                            ii.                Implement a function and take the CancellationTokenSource object as one of the parameters.

Check the state of IsCancellationRequested in the thread. If the state is “true”, that means the thread should be cancelled.

/// <summary>
///
Task要做的事
/// </summary>
///
<param name="x"></param>
private static bool taskJob(int x, CancellationToken _ct)
{
  try
 
{
      for (int i = 0; i < x; i++)
      {
         if (_ct.IsCancellationRequested == true)
          {
            return false;
          }
          Console.WriteLine(i.ToString());
       }
   return true;
  }
  catch (Exception)
  {
    return false;
  }
}


                        iii.                Define a Task and add the functionCancellationTokenSource object as parameters.
//宣告Task
Task<bool> _task = new Task<bool>(
      () => taskJob(10000, cts.Token), cts.Token  );

                          iv.                Start the task, then cancel it.

//啟動Task
_task.Start();
//
建立當目標 System.Threading.Tasks.Task<TResult> 完成時隨即執行的接續工作。
//_task.ContinueWith(TaskEnded)

Thread.Sleep(1500);
cts.Cancel();


                           v.                Output result :

5738
5739
5740
中途結束Task!


l   Use CancellationTokenSource and cancel the thread by calling ThrowIfCancellationRequested.

                            i.                Define a CancellationTokenSource object.
(The same as the above sample code)

                            ii.                Implement a function and take the CancellationTokenSource object as one of the parameters.

Call the ThrowIfCancellationRequested() to check if the CancellationTokenSource is canceled in the main thread.
If the CancellationTokenSource is cancelled, ThrowIfCancellationRequested() will throw an exception!

/// <summary>
///
Task要做的事
/// </summary>
///
<param name="x"></param>
private static bool taskJob(int x, CancellationToken _ct)
{

 
try
 
{
      for (int i = 0; i < x; i++)
      {
         //
呼叫ThrowIfCancellationRequested判斷是否已經取消Tocken
       
_ct.ThrowIfCancellationRequested();
       
         Console.WriteLine(i.ToString());
       }
       return true;
   }
   catch (Exception)
   {
     return false;
   }
 }



                        iii.                Define a Task and add the functionCancellationTokenSource object as parameters.
(The same as the above sample code)
                         iv.                Start the task, then cancel it.
(The same as the above sample code)

                           v.                Output result :


5368
5369
中途結束Task!


四、TaskFactory

l   Add multi Task to TaskFactoryand start them

Notice that you may what to put the return Task object of calling
taskFactory.StartNew()  into a Task array, which can be used to set the continued work later.

//宣告TaskFactory
TaskFactory taskFactory = new System.Threading.Tasks.TaskFactory();

//加入Task到工廠並啟動
Task[] tasks = new Task[3]
{
  taskFactory.StartNew( () => taskJob(10000, cts.Token)),
  taskFactory.StartNew( () => taskJob(10000, cts.Token)),
  taskFactory.StartNew( () => taskJob(10000, cts.Token))
};


l   Create a continued works when the tasks finish.

 taskFactory.ContinueWhenAll (tasks, TaskEnded, cts.Token);
//
參數 tasks : Task[] 集合
//
參數 TaskEnded : 要接續的工作 (function name)
//
參數 cts.Token : cts CancellationTokenSource 物件

l   Output result :
2581
2582
2583
2049
2050
2051
2052
2053


The number will appear with the switch of threads.

l   Reference
MSDN

沒有留言:

張貼留言