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;
}
}
/// <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, 並指定Action給Task
Task _task = new Task(
() => taskJob(100)
);
// 宣告Task, 並指定Action給Task
Task _task = new Task(
() => taskJob(100)
);
l Run it!
_task.Start();
_task.Start();
l Output result :
…
97
98
99
總值為=4950
…
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;
}
}
/// <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)
);
// 宣告Task, 並指定可Return值的Func 給Task
Task<double> _task = new Task<double>(
() => taskJob(100)
);
l Run it!
//開始執行Task
_task.Start();
//開始執行Task
_task.Start();
l Get the result from the Task
//取得Task Return 結果
double _rslt = _task.Result;
Console.WriteLine("總值={0}", _rslt.ToString());
//取得Task Return 結果
double _rslt = _task.Result;
Console.WriteLine("總值={0}", _rslt.ToString());
l Output result :
…
97
98
99
總值=4950
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!");
});
// 向 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;
}
}
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
function、CancellationTokenSource object as parameters.
//宣告Task
Task<bool> _task = new Task<bool>(
() => taskJob(10000, cts.Token), cts.Token );
//宣告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();
//啟動Task
_task.Start();
//建立當目標 System.Threading.Tasks.Task<TResult> 完成時隨即執行的接續工作。
//_task.ContinueWith(TaskEnded)
Thread.Sleep(1500);
cts.Cancel();
v.
Output
result :
…
5738
5739
5740
中途結束Task!
…
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)
(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;
}
}
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
function、CancellationTokenSource object as parameters.
(The same as the above sample code)
(The same as the above sample code)
iv.
Start the task, then cancel it.
(The same as the above sample code)
(The same as the above sample code)
v.
Output
result :
…
5368
5369
中途結束Task!
…
5368
5369
中途結束Task!
四、TaskFactory
l
Add multi
Task to TaskFactory,and 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))
};
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 物件
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
MSDN
沒有留言:
張貼留言