欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.Net使用Cancellation?Framework取消并行任務(wù)

 更新時(shí)間:2022年06月17日 09:41:19   作者:天方  
這篇文章介紹了.Net使用Cancellation?Framework取消并行任務(wù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

在.net 4.0中,引入了一個(gè)新的類CancellationToken,這個(gè)類基本上集成了我們各種常用的取消方式,在并發(fā)任務(wù)中非常有用。

同步模式下的取消:

一種比較常見的需要支持取消功能的的是一些比較耗時(shí)的分段操作:如視頻轉(zhuǎn)換,網(wǎng)絡(luò)下載等,這種方式下的取消機(jī)制如下:

  • 建立一個(gè)標(biāo)記位,表示該操作是否已經(jīng)取消

  • UI線程在獲取到取消事件后,置標(biāo)記位為true

  • 耗時(shí)的操作線程里,沒進(jìn)行一小段操作之后查詢?cè)摌?biāo)記位,如果為true則主動(dòng)退出。

使用方式如下:

    EventHandler externalEvent;
    void Example1()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        externalEvent +=
         (sender, obj) => { cts.Cancel(); }; //wire up an external requester 
        try
        {
            int val = LongRunningFunc(cts.Token);
        }
        catch (OperationCanceledException)
        {
            //cleanup after cancellation if required... 
        }
    }

    private static int LongRunningFunc(CancellationToken token)
    {
        int total = 0;
        for (int i = 0; i < 1000; i++)
        {
            for (int j = 0; j < 1000; j++)
            {
                total++;
            }
            if (token.IsCancellationRequested)
            { // observe cancellation 
                throw new OperationCanceledException(token); // acknowledge cancellation 
            }
        }
        return total;
    }

異步模式下的取消

另外一種常見的方式是在一些異步操作中,往往不能主動(dòng)釋放,只能等待異步操作回調(diào)的時(shí)候才能操作結(jié)果。此時(shí)一般取消方法如下:

  • 任務(wù)線程注冊(cè)異步操作完成的回調(diào)函數(shù),開始異步操作。

  • UI線程接受取消指令,置取消標(biāo)記位,并主動(dòng)執(zhí)行回調(diào)函數(shù)

  • 回調(diào)函數(shù)中通過(guò)取消標(biāo)記位判斷該任務(wù)是已經(jīng)完成還是被取消的,并執(zhí)行相關(guān)析構(gòu)操作。

使用方式如下:

    void BlockingOperation(CancellationToken token)
    {
        ManualResetEvent mre = new ManualResetEvent(false);
        //register a callback that will set the MRE 
        CancellationTokenRegistration registration =
         token.Register(() => mre.Set());
        using (registration)
        {
            mre.WaitOne();
            if (token.IsCancellationRequested) //did cancellation wake us? 
                throw new OperationCanceledException(token);
        } //dispose the registration, which performs the deregisteration. 
    }

這里我們通過(guò)CancellationToken注冊(cè)了一個(gè)回調(diào)方法以通知任務(wù)等待線程,也可以以我們經(jīng)常使用的WaitHandle的那樣的方式使用。

    void Wait(WaitHandle wh, CancellationToken token)
    {
        WaitHandle.WaitAny(new[] { wh, token.WaitHandle });
        if (token.IsCancellationRequested) //did cancellation wake us? 
            throw new OperationCanceledException(token);
    }

高級(jí)應(yīng)用

由于例子比較簡(jiǎn)單,這里就只列舉一下代碼,不多介紹了。

一個(gè)CancellationToken對(duì)應(yīng)多個(gè)任務(wù)

    void Example4()
    {
        CancellationTokenSource cts = new CancellationTokenSource();
        Func1(cts.Token);
        Func2(cts.Token);
        Func3(cts.Token);
        //... 
        cts.Cancel(); // all listeners see the same cancellation request. 
    }

一個(gè)任務(wù)對(duì)應(yīng)多個(gè)CancellationToken

    void LinkingExample(CancellationToken ct1, CancellationToken ct2)
    {
        CancellationTokenSource linkedCTS =
        CancellationTokenSource.CreateLinkedTokenSource(ct1, ct2);
        try
        {
            SlowFunc(linkedCTS.Token);
        }
        catch (OperationCanceledException oce)
        {
            if (ct1.IsCancellationRequested)
            {
                // ... 
            }
            else if (ct2.IsCancellationRequested)
            {
                // ... 
            }
        }
        linkedCTS.Dispose(); // clean up the linking. required. 
    }

最后我們?cè)賮?lái)一個(gè)并發(fā)查詢時(shí)取消的例子:

    private void RunQuery()
    {
        int[] data = { 1, 2, 3 };
        CancellationTokenSource cts = new CancellationTokenSource();
        var query = data.AsParallel()
                     .WithCancellation(cts.Token) // token given to library code 
                     .Select((x) => SlowFunc(x, cts.Token)); // token passed to user code 
    }

    private int SlowFunc(int x, CancellationToken token) 
    { 
        int result 
        while(...) 
        { 
            if (token.IsCancellationRequested) 
            throw new OperationCanceledException(token); 
            ... 
        } 
        return result; 
    }

小結(jié)

.net 4.0中的Cancellation Framework還是非常實(shí)用的,通過(guò)它可以更有效的簡(jiǎn)化及規(guī)范的使用各種取消的操作方式,由于我也只會(huì)皮毛,在這里也只是介紹了它的基本用法,在后續(xù)的學(xué)習(xí)和應(yīng)用中將繼續(xù)進(jìn)一步介紹。

到此這篇關(guān)于.Net使用Cancellation Framework取消并行任務(wù)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論