.Net中Task Parallel Library的進階用法
在前一篇中,了解了Task的基本用法
如果一個方法返回Task,Task<T>,如何獲取Task的返回值,獲取值的過程會阻塞線程嗎?
static void Main(string[] args)
{
var result = DoWorkAsync().Result;
Console.WriteLine(result);
Console.WriteLine("我會什么時候顯示");
Console.ReadKey();
}
static Task<string> DoWorkAsync()
{
return Task<string>.Factory.StartNew(() =>
{
Thread.Sleep(3000);
return "hello";
});
}
可見,Task的Result屬性可以獲取返回值,而且,獲取返回值的過程線程是被阻塞的。
是否可以不阻塞線程,又能拿到某個線程的返回值呢?ContinueWith方法在某個線程結(jié)束之后進行,但同時不會阻塞線程。
static void Main(string[] args)
{
DoWorkAsync().ContinueWith((pre) =>
{
Console.WriteLine(pre.Result);
});
Console.WriteLine("我會什么時候顯示");
Console.ReadKey();
}
但ContinueWith總會在某個線程結(jié)束之后進行,是否可以對ContinueWith的過程控制一下呢?
static void Main(string[] args)
{
DoWorkAsync().ContinueWith((pre) =>
{
Console.WriteLine(pre.Result);
}, TaskContinuationOptions.NotOnFaulted);
DoWorkAsync().ContinueWith((pre) =>
{
Console.WriteLine(pre.Exception);
},TaskContinuationOptions.OnlyOnFaulted);
Console.WriteLine("我會什么時候顯示");
Console.ReadKey();
}以上,當(dāng)沒有錯誤的時候就把返回值顯示出來,有錯誤就把錯誤信息顯示出來。
還可以通過Task的實例方法IsCompleted來判斷一個線程是否完成。
static void Main(string[] args)
{
var doWorkTask = DoWorkAsync();
if (doWorkTask.IsCompleted)
{
Console.WriteLine(doWorkTask.Result);
}
else
{
doWorkTask.ContinueWith((pre) =>
{
Console.WriteLine(pre.Result);
}, TaskContinuationOptions.NotOnFaulted);
doWorkTask.ContinueWith((pre) =>
{
Console.WriteLine(pre.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
}
Console.WriteLine("我會什么時候顯示");
Console.ReadKey();
}Task的Status屬性,以及結(jié)合TaskStatus枚舉,可以判斷Task的狀態(tài)。
static void Main(string[] args)
{
var httpClient = new HttpClient();
Task<string> baiduTask = httpClient.GetStringAsync("http://www.baidu.com");
var httpClient2 = new HttpClient();
Task<string> sinaTask = httpClient2.GetStringAsync("http://www.sina.com.cn");
//等上面2個任務(wù)完成時這里再開始
Task<string[]> task = Task.WhenAll(baiduTask, sinaTask);
task.ContinueWith(stringArray =>
{
//如果任務(wù)完成
if (task.Status == TaskStatus.RanToCompletion)
{
for (int i = 0; i < stringArray.Result.Length;i++)
{
Console.WriteLine(stringArray.Result[i].Substring(0,100));
}
}
else if (task.Status == TaskStatus.Canceled) //如果被取消
{
Console.WriteLine("{0}這個任務(wù)被取消了",task.Id);
}
else //發(fā)生錯誤
{
Console.WriteLine("發(fā)生錯誤了~~");
foreach (var item in task.Exception.InnerExceptions)
{
Console.WriteLine(item.Message);
}
}
});
Console.ReadKey();
}如果要控制Task的生命周期,可以考慮使用TaskCompletionSource<T>。
static void Main(string[] args)
{
AsyncFactory.GetIntAsync().ContinueWith((prev) =>
{
if (prev.Status == TaskStatus.RanToCompletion)
{
Console.WriteLine(prev.Result);
}
else if (prev.Status == TaskStatus.Canceled)
{
Console.WriteLine("任務(wù)被取消");
}
else
{
Console.WriteLine("發(fā)生錯誤哦");
Console.WriteLine(prev.Exception);
}
});
Console.ReadKey();
}
}
public static class AsyncFactory
{
public static Task<int> GetIntAsync()
{
var tsc = new TaskCompletionSource<int>();
var timer = new System.Timers.Timer(2000);
timer.AutoReset = false;
timer.Elapsed += (s, e) =>
{
tsc.SetResult(10);
timer.Dispose();
};
timer.Start();
return tsc.Task;
}
}以上,通過TaskCompletionSource<T>的SetResult給線程設(shè)置返回值,通過TaskCompletionSource<T>的.Task有獲取了線程。
另外,從.NET 4.5開始,Task的靜態(tài)方法FromResult,接收T類型,返回Task<T>。
static void Main(string[] args)
{
var intTask = GetIntAsync();
if (intTask.Status == TaskStatus.RanToCompletion)
{
Console.WriteLine(intTask.Result);
}
else if (intTask.Status == TaskStatus.Canceled)
{
Console.WriteLine("任務(wù)被取消");
}
else
{
Console.WriteLine("發(fā)生錯誤哦");
Console.WriteLine(intTask.Exception);
}
Console.ReadKey();
}
static Task<int> GetIntAsync()
{
return Task.FromResult(10);
}以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接
相關(guān)文章
Asp.net管理信息系統(tǒng)中數(shù)據(jù)統(tǒng)計功能的實現(xiàn)方法
這篇文章主要介紹了Asp.net管理信息系統(tǒng)中數(shù)據(jù)統(tǒng)計功能的實現(xiàn)方法,需要的朋友可以參考下2017-07-07
subsonic3.0插件更新字符串過長引發(fā)的異常修復(fù)方法
這篇文章主要介紹了subsonic3.0插件更新字符串過長引發(fā)的異常修復(fù)方法,需要的朋友可以參考下2014-04-04
Asp.net圖片上傳實現(xiàn)預(yù)覽效果的簡單代碼
這篇文章介紹了Asp.net圖片上傳實現(xiàn)預(yù)覽效果的簡單代碼,有需要的朋友可以參考一下2013-07-07
asp.net實現(xiàn)生成靜態(tài)頁并添加鏈接的方法
這篇文章主要介紹了asp.net實現(xiàn)生成靜態(tài)頁并添加鏈接的方法,非常實用的功能,需要的朋友可以參考下2014-07-07

