狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

深入理解C#中的Task類:創建、執行和取消異步操作

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

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

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

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

創建和運行任務

創建和執行任務的最常見方法是使用 Task.Run() 或 TaskFactory.StartNew() 方法。

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

將參數傳遞給任務

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

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

取消任務

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

在主線程中,創建一個 CancellationTokenSource 對象。 將 CancellationTokenSource.Token 屬性傳遞給創建的所有任務。 定期檢查任務中的 CancellationToken.IsCancellationRequested 屬性,并相應地處理取消。 在主線程中,調用 CancellationTokenSource.Cancel() 方法。Cancel() 方法會將 CancellationToken.IsCancellationRequested 屬性設置為 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();        }    }}

取消阻止任務

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

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

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

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

WaitOne() 方法中的參數 (1000) 是以毫秒為單位的超時值。返回值 false 表示發生超時;返回值 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();            }        }    }}

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

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

當應用程序被 GetContextAsync() 方法阻止時,您將如何調用 HttpListener.Stop() 方法?您可以使用 CancellationToken.Register() 方法注冊一個委托,該委托將在取消此 CancellationToken 時調用。

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 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved