C#異步編程Task的創(chuàng)建方式
一、簡介
ThreadPool相比Thread來說具備了很多優(yōu)勢,但是ThreadPool卻又存在一些使用上的不方便。比如:
Task支持線程的取消、完成、失敗通知等交互性操作,但是ThreadPool不支持;
Task支持線程執(zhí)行的先后次序,但是ThreadPool不支持;;
以往,如果開發(fā)者要實現(xiàn)上述功能,需要完成很多額外的工作,現(xiàn)在,F(xiàn)CL中提供了一個功能更強大的概念:Task。Task在線程池的基礎(chǔ)上進行了優(yōu)化,并提供了更多的API。在FCL4.0中,如果我們要編寫多線程程序,Task顯然已經(jīng)優(yōu)于傳統(tǒng)的方式。
Task t = new Task(() =>
{
Console.WriteLine("Start……");
//模擬工作過程
Thread.Sleep(5000);
});
t.Start();
t.ContinueWith((task) =>
{
Console.WriteLine("Already Finished,States:");
Console.WriteLine("IsCanceled={0}\tIsCompleted={1}\tIsFaulted={2}", task.IsCanceled, task.IsCompleted, task.IsFaulted);
});
Console.ReadKey();二、Task創(chuàng)建
無返回值創(chuàng)建方式
線程引用方法:
static void TaskMethod(string name)
{
Console.WriteLine("Task: {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
}方式一:
//方式一
var t1 = new Task(() => TaskMethod("Task_1"));
t1.Start();
//等待所有任務(wù)結(jié)束
//任務(wù)的狀態(tài):
//Start之前為:Created
//Start之后為:WaitingToRun
Task.WaitAll(t1);////等待所有任務(wù)結(jié)束方式二:
//方式二
Task.Run(() => TaskMethod("Task_2"));方式三:
//方式三
Task.Factory.StartNew(() => TaskMethod("Task_3")); //直接異步的方法
//或者
var t3 = Task.Factory.StartNew(() => TaskMethod("Task_3"));
Task.WaitAll(t3);//等待所有任務(wù)結(jié)束
//任務(wù)的狀態(tài)
//Start之前為:Running
//Start之后為:Running實例:
class Program
{
static void Main(string[] args)
{
var t1 = new Task(() => TaskMethod("Task_1"));
var t2 = new Task(() => TaskMethod("Task_2"));
t2.Start();
t1.Start();
Task.WaitAll(t1, t2);
Task.Run(() => TaskMethod("Task_3"));
Task.Factory.StartNew(() => TaskMethod("Task_4"));
//標記為長時間運行任務(wù),則任務(wù)不會使用線程池,而在單獨的線程中運行。
Task.Factory.StartNew(() => TaskMethod("Task_5"), TaskCreationOptions.LongRunning);
#region 常規(guī)的使用方式
Console.WriteLine("主線程執(zhí)行業(yè)務(wù)處理.");
//創(chuàng)建任務(wù)
Task task = new Task(() =>
{
Console.WriteLine("使用System.Threading.Tasks.Task執(zhí)行異步操作.");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(i);
}
});
//啟動任務(wù),并安排到當前任務(wù)隊列線程中執(zhí)行任務(wù)(System.Threading.Tasks.TaskScheduler)
task.Start();
Console.WriteLine("主線程執(zhí)行其他處理");
task.Wait();
#endregion
Thread.Sleep(TimeSpan.FromSeconds(1));
Console.ReadLine();
}
static void TaskMethod(string name)
{
Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
}
}結(jié)果:

async/await的實現(xiàn)方式:
class Program
{
async static void AsyncFunction()
{
await Task.Delay(1);
Console.WriteLine("使用System.Threading.Tasks.Task執(zhí)行異步操作.");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(string.Format("AsyncFunction:i={0}", i));
}
}
public static void Main()
{
Console.WriteLine("主線程執(zhí)行業(yè)務(wù)處理.");
AsyncFunction();
Console.WriteLine("主線程執(zhí)行其他處理");
for (int i = 0; i < 10; i++)
{
Console.WriteLine(string.Format("Main:i={0}", i));
}
Console.ReadLine();
}
}結(jié)果:

帶返回值方式
線程引用方法
static Task<int> CreateTask(string name)
{
return new Task<int>(() => TaskMethod1(name));
} static int TaskMethod1(string name)
{
Console.WriteLine("Task {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(2));
return 42;
}方式四:
//方式四
Task<int> task = CreateTask("Task_1");
task.Start();
int result = task.Result;實例:
class Program
{
static Task<int> CreateTask(string name)
{
return new Task<int>(() => TaskMethod(name));
}
static void Main(string[] args)
{
TaskMethod("Main Thread Task");
Task<int> task = CreateTask("Task_1");
task.Start();
int result = task.Result;
Console.WriteLine("Task_1 Result is: {0}", result);
task = CreateTask("Task_2");
//該任務(wù)會運行在主線程中
task.RunSynchronously();
result = task.Result;
Console.WriteLine("Task_2 Result is: {0}", result);
task = CreateTask("Task_3");
Console.WriteLine(task.Status);
task.Start();
while (!task.IsCompleted)
{
Console.WriteLine(task.Status);
Thread.Sleep(TimeSpan.FromSeconds(0.5));
}
Console.WriteLine(task.Status);
result = task.Result;
Console.WriteLine("Task_3 Result is: {0}", result);
#region 常規(guī)使用方式
//創(chuàng)建任務(wù)
Task<int> getsumtask = new Task<int>(() => Getsum());
//啟動任務(wù),并安排到當前任務(wù)隊列線程中執(zhí)行任務(wù)(System.Threading.Tasks.TaskScheduler)
getsumtask.Start();
Console.WriteLine("主線程執(zhí)行其他處理");
//等待任務(wù)的完成執(zhí)行過程。
getsumtask.Wait();
//獲得任務(wù)的執(zhí)行結(jié)果
Console.WriteLine("任務(wù)執(zhí)行結(jié)果:{0}", getsumtask.Result.ToString());
Console.ReadLine();
#endregion
}
static int TaskMethod(string name)
{
Console.WriteLine("Task: {0} is running on a thread id {1}. Is thread pool thread: {2}",
name, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
Thread.Sleep(TimeSpan.FromSeconds(2));
return 42;
}
static int Getsum()
{
int sum = 0;
Console.WriteLine("使用Task執(zhí)行異步操作.");
for (int i = 0; i < 100; i++)
{
sum += i;
}
return sum;
}
}結(jié)果:

async/await的實現(xiàn):
class Program
{
public static void Main()
{
var ret1 = AsyncGetsum();
Console.WriteLine("主線程執(zhí)行其他處理");
for (int i = 1; i <= 3; i++)
Console.WriteLine("Call Main()");
int result = ret1.Result; //阻塞主線程
Console.WriteLine("任務(wù)執(zhí)行結(jié)果:{0}", result);
Console.ReadLine();
}
async static Task<int> AsyncGetsum()
{
await Task.Delay(1);
int sum = 0;
Console.WriteLine("使用Task執(zhí)行異步操作.");
for (int i = 0; i < 100; i++)
{
sum += i;
}
return sum;
}
}結(jié)果:

到此這篇關(guān)于C#創(chuàng)建異步Task的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于WebClient實現(xiàn)Http協(xié)議的Post與Get對網(wǎng)站進行模擬登陸和瀏覽實例
這篇文章主要介紹了基于WebClient實現(xiàn)Http協(xié)議的Post與Get對網(wǎng)站進行模擬登陸和瀏覽的方法,以實例形式詳細分析了WebClient模擬POST與GET登陸與瀏覽的過程,對于C#項目開發(fā)來說具有不錯的參考借鑒價值,需要的朋友可以參考下2014-11-11
C# 實現(xiàn)dataGridView選中一行右鍵出現(xiàn)菜單的示例代碼
這篇文章主要介紹了C# 實現(xiàn)dataGridView選中一行右鍵出現(xiàn)菜單,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
基于C#調(diào)用c++Dll結(jié)構(gòu)體數(shù)組指針的問題詳解
下面小編就為大家分享一篇基于C#調(diào)用c++Dll結(jié)構(gòu)體數(shù)組指針的問題詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
淺談c#.net中巧用ToString()將日期轉(zhuǎn)成想要的格式
有時候我們要對時間進行轉(zhuǎn)換,達到不同的顯示效果,更多的該怎么辦呢?2013-03-03
Winform動態(tài)加載TabControl用法實例
這篇文章主要介紹了Winform動態(tài)加載TabControl用法,以實例形式詳細講述了Winform動態(tài)加載TabControl的方法,在C#應(yīng)用程序開發(fā)中具有一定的實用價值,需要的朋友可以參考下2014-11-11
Unity 實現(xiàn)框選游戲戰(zhàn)斗單位的思路詳解
這篇文章主要介紹了Unity 如何實現(xiàn)框選游戲戰(zhàn)斗單位,本文簡單介紹如何實現(xiàn)即時戰(zhàn)略游戲中框選戰(zhàn)斗單位的功能,需要的朋友可以參考下2022-12-12
C#實現(xiàn)的Windows剪貼板監(jiān)視器功能實例【附demo源碼下載】
這篇文章主要介紹了C#實現(xiàn)的Windows剪貼板監(jiān)視器功能,結(jié)合實例形式分析了C#實現(xiàn)剪貼板監(jiān)視功能所涉及的相關(guān)Windows API函數(shù)與使用技巧,需要的朋友可以參考下2016-08-08

