《C#並行編程高級教程》第9章 異步編程模型 筆記

這個章節我我的感受意義不大,使用現有的APM(異步編程模型)和EAP(基於時間的異步模型)就很夠用了,針對WPF和WinForm其實還有一些專門用於UI更新的類。
可是出於完整性,仍是將一下怎麼使用.NET4的並行擴展,也就是一直在使用Task模型來處理異步問題。有一個特別好處是,當有大量併發的IO操做時會有更好的效果。
大量併發的IO操做的含義是相似以下
private List <Task < int >> tasks;
有一堆的task,其中的每個task都是一個異步的IO操做。

APM->Task

而一個整和APM的task產生方法以下
Task < int > task =
    Task < int >.Factory.FromAsync(
    stream.BeginRead, stream.EndRead,
    data, 0, data.Length, null,
    TaskCreationOptions.None);
另外不須要調用task的Start方法

EAP->Task

使用TaskCompletionSource<TResult>能夠將一個EAP操做表示爲一個Task<TResult>
使用TaskCompletionSource的幾個方法能夠嘗試將底層的Task轉換到某個特定的狀態
TrySetCanceled:task轉換成TaskStatusCanceled
SetException:task轉換成TaskStatusFaulted
TrySetResult:task轉換成TaskStatusRanToCompletion
 
下面以WebClient.DownloadFileAsync爲例,演示如何將一個EAP的操做處理成一個Task對象
var tcs = new TaskCompletionSource < string >();
 
var wc = new WebClient();
 
AsyncCompletedEventHandler handler   =
    (hSender, hE) = >
    {
         if (hE.Error != null)
        {
            tcs.TrySetException(hE.Error);
        }
         else if (hE.Cancelled)
        {
            tcs.TrySetCanceled();
        }
         else
        {
            tcs.TrySetResult(fileName);
        }
        wc.DownloadFileCompleted -= handler;
    };
 
wc.DownloadFileCompleted += handler;
 
try
{
    wc.DownloadFileAsync(address, fileName);
}
catch (Exception ex)
{
    wc.DownloadFileCompleted -= handler;
    tcs.TrySetException(ex);
}
 
Task task = tcs.Task;

UI的更新

不管是WPF仍是WinForm,UI控件只能在UI線程進行操做。他們都有各自的多種方案。
而使用Task模型的方案是使用一個TaskScheduler.FromCurrentSynchronizationContext();獲取一個TaskScheduler,使用TaskScheduler執行的Task就是在UI線程下的。
var uiScheduler =
    TaskScheduler.FromCurrentSynchronizationContext();
var builderTask = //...一個不修改UI的任務
builderTask.ContinueWith(
        (t) = >
        {
             //..在這裏進行UI的更新
        }, uiScheduler);
 
 


相關文章
相關標籤/搜索