LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

深入理解C#中的Task類:創(chuàng)建、執(zhí)行和取消異步操作

admin
2024年2月21日 12:17 本文熱度 1675

概述:Task類是.NET Framework 4中引入的關(guān)鍵組件,用于表示異步執(zhí)行的單個(gè)操作。它比線程更輕量級,適合快速執(zhí)行小型異步任務(wù)。本文介紹了創(chuàng)建、運(yùn)行任務(wù)的方法以及任務(wù)取消的機(jī)制,包括使用CancellationTokenSource對象取消任務(wù)和處理阻塞任務(wù)的方法。

Task 類表示通常異步執(zhí)行的單個(gè)操作。Task 對象是 .NET Framework 4 中首次引入的基于任務(wù)的異步模式的核心組件之一。

任務(wù)比線程更輕量級。默認(rèn)任務(wù)計(jì)劃程序在線程池內(nèi)運(yùn)行任務(wù)。因此,Task 更適合運(yùn)行小型、快速的異步操作。如果使用任務(wù)運(yùn)行許多長時(shí)間運(yùn)行的任務(wù),則可能會(huì)用完線程池中的所有線程,并且新任務(wù)必須等待以前的任務(wù)完成執(zhí)行。

創(chuàng)建和運(yùn)行任務(wù)

創(chuàng)建和執(zhí)行任務(wù)的最常見方法是使用 Task.Run() 或 TaskFactory.StartNew() 方法。

Task.Run 和 TaskFactory.StartNew 之間的主要區(qū)別在于,可以使用 TaskFactory.StartNew 將參數(shù)傳遞給任務(wù)。

將參數(shù)傳遞給任務(wù)

public System.Threading.Tasks.Task StartNew (Action<object?> action, object? state);

TaskFactory.StartNew() 的一個(gè)重載方法采用兩個(gè)參數(shù):第一個(gè)是異步執(zhí)行的操作委托,第二個(gè) () 是傳遞到操作委托的參數(shù)。第二個(gè)參數(shù)是類型。您可以將任何單個(gè)對象作為參數(shù)傳入,并在任務(wù)中將其轉(zhuǎn)換為其原始類型。stateobject

取消任務(wù)

Task 類支持通過使用 CancellationTokenSource 對象進(jìn)行取消。此對象具有 Token 屬性和 Cancel() 方法。以下是任務(wù)取消的工作原理:

在主線程中,創(chuàng)建一個(gè) CancellationTokenSource 對象。 將 CancellationTokenSource.Token 屬性傳遞給創(chuàng)建的所有任務(wù)。 定期檢查任務(wù)中的 CancellationToken.IsCancellationRequested 屬性,并相應(yīng)地處理取消。 在主線程中,調(diào)用 CancellationTokenSource.Cancel() 方法。Cancel() 方法會(huì)將 CancellationToken.IsCancellationRequested 屬性設(shè)置為 true。

using System;using System.Threading;using System.Threading.Tasks;
namespace ConsoleApp1{    internal class Program    {        static void Main(string[] args)        {            var tokenSource = new CancellationTokenSource();            var token = tokenSource.Token;
           Task.Run(() =>            {                int count = 1;                while (!token.IsCancellationRequested)                {                    Thread.Sleep(1000);                    Console.WriteLine($"Sleep {count++} seconds");                }                Console.WriteLine($"Cancellation requested.");            }, token);
           var key = Console.ReadKey();
           while (key.KeyChar != 'c')            {                key = Console.ReadKey();            }
           tokenSource.Cancel();            Console.WriteLine($"Send Cancel command and exit.");
           Console.ReadKey();        }    }}

取消阻止任務(wù)

如您所見,上述取消機(jī)制依賴于定期檢查 CancellationToken.IsCancellationRequested 屬性。如果我的任務(wù)是阻塞方法調(diào)用怎么辦?遺憾的是,沒有適用于所有方案的通用解決方案。

如果方法支持 Begin/End 異步 API

如果要調(diào)用的阻止方法還提供異步替代方法,則可以利用從 Begin... () 方法創(chuàng)建輪詢情境。

if (result.AsyncWaitHandle.WaitOne(1000)) 
{
  // At this point, asynchronous operation completed
  Console.WriteLine("Request processed asyncronously.");
};

WaitOne() 方法中的參數(shù) (1000) 是以毫秒為單位的超時(shí)值。返回值 false 表示發(fā)生超時(shí);返回值 true 表示異步操作完成。

using System;using System.Net;using System.Threading;using System.Threading.Tasks;
namespace ConsoleApp2{    internal class Program    {        private static readonly HttpListener listener = new HttpListener { Prefixes = { $"http://localhost:8098/" } };        static void Main(string[] args)        {            CancellationTokenSource tokenSource = new CancellationTokenSource();            CancellationToken token = tokenSource.Token;            Task.Run(() =>            {                listener.Start();                int count = 1;                while (!token.IsCancellationRequested)                {                    var result = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);                    Console.WriteLine($"{count++}: Waiting for request to be processed asyncronously.");                    if (result.AsyncWaitHandle.WaitOne(1000))                    {                        Console.WriteLine("Request processed asyncronously.");                    };                }                listener.Close();            }, token);            var key = Console.ReadKey();
           while (key.KeyChar != 'c')            {                key = Console.ReadKey();            }
           tokenSource.Cancel();            Console.WriteLine($"Send Cancel command and exit.");
           Console.ReadKey();        }
       private static void ListenerCallback(IAsyncResult result)        {            HttpListener listener = (HttpListener)result.AsyncState;            if (listener.IsListening)            {                HttpListenerContext context = listener.EndGetContext(result);                HttpListenerResponse response = context.Response;                string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);                response.ContentLength64 = buffer.Length;                System.IO.Stream output = response.OutputStream;                output.Write(buffer, 0, buffer.Length);                output.Close();            }        }    }}

如果該方法可以被其他操作中斷

這更具體地適用于您調(diào)用的方法。有些方法可能支持這種情況,有些方法不支持。讓我們以 HttpListener 為例。HttpListener 具有 GetContextAsync() 方法。此方法將阻止任務(wù)。但是,如果調(diào)用 HttpListener.Stop() 方法,它將引發(fā) HttpListenerException,從而取消阻止 GetContextAsync() 方法。

當(dāng)應(yīng)用程序被 GetContextAsync() 方法阻止時(shí),您將如何調(diào)用 HttpListener.Stop() 方法?您可以使用 CancellationToken.Register() 方法注冊一個(gè)委托,該委托將在取消此 CancellationToken 時(shí)調(diào)用。

using System;using System.Net;using System.Threading;using System.Threading.Tasks;
namespace ConsoleApp3{    internal class Program    {        private static readonly HttpListener listener = new HttpListener { Prefixes = { $"http://localhost:8098/" } };        static void Main(string[] args)        {            CancellationTokenSource tokenSource = new CancellationTokenSource();            CancellationToken token = tokenSource.Token;            token.Register(() =>            {                if (listener.IsListening)                {                    listener.Stop();                }            });            Task.Run(async () =>            {                listener.Start();                while (!token.IsCancellationRequested)                {                    try                    {                        Console.WriteLine("Waiting for request to come...");                        var context = await listener.GetContextAsync();                        SendResponse(context);                        Console.WriteLine("Request processed asyncronously.");                    }                    catch (Exception e)                    {                        if (e is HttpListenerException)                        {                            //this gets thrown when the listener is stopped                            Console.WriteLine($"Task received cancel request and exit.");                            return;                        }                        Console.WriteLine(e.Message);                    }                }                listener.Close();            }, token);            var key = Console.ReadKey();
           while (key.KeyChar != 'c')            {                key = Console.ReadKey();            }
           tokenSource.Cancel();            Console.WriteLine($"Main thread sent Cancel command and exit.");
           Console.ReadKey();        }
       private static void SendResponse(HttpListenerContext context)        {            Console.WriteLine($"Send hello word response.");
           HttpListenerResponse response = context.Response;            string responseString = "<HTML><BODY> Hello world!</BODY></HTML>";            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);            response.ContentLength64 = buffer.Length;            System.IO.Stream output = response.OutputStream;            output.Write(buffer, 0, buffer.Length);            output.Close();        }    }}


該文章在 2024/2/21 12:17:13 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
在线欧美AⅤ整片 | 在线免费观看的三级网站 | 中文字幕福利在线观看 | 日韩精品有码中文字幕 | 五月天在线视频婷婷播放 | 伊人久久大香线蕉综合网站 |