C# 非同期 APM モードの非同期プログラム開発例の共有
C# には 10 年以上の歴史があり、Microsoft の 2 年ごとのアップデートの進捗から判断すると、C# の非同期プログラミングも複数のバージョンの進化を経験しています。 C# における非同期プログラミングの開発履歴を記録する投稿です。 広告: 私の記事が気に入ったお友達は、下の「フォローする」をクリックしてください。ありがとうございます
私がC#に触れて使ったのは2004年です。当時のC#のバージョンは1.1だったので、その頃からお話します。当時、大学で自分でプログラムを読んだり書いたりしていたとき、私が書いたプログラムのほとんどは同期プログラムで、せいぜい 1 つのスレッドしか起動できませんでした。実際、C# 1.1 の時代には、完全なプログラムがありました。非同期プログラミング ソリューション、それが APM (非同期プログラミング モデル) でした。 「同期プログラムと非同期プログラム」がまだわからない場合は、Baidu にアクセスしてください。
APM 非同期プログラミング モデルの最も代表的な特徴は、非同期関数が Begin と End で始まる 2 つのメソッドで構成されることです。 Beginで始まるメソッドは非同期関数の実行を開始することを意味し、Endで始まるメソッドは非同期関数の実行が終了するのを待って実行結果を返すことを意味します。以下はシミュレーションの実装です (標準の APM モデルの非同期実装は後で記述します):
public class Worker { public int A { get; set; } public int B { get; set; } private int R { get; set; } ManualResetEvent et; public void BeginWork(Action action) { et = new ManualResetEvent(false); new Thread(() => { R = A + B; Thread.Sleep(1000); et.Set(); if(null != action) { action(); } }).Start(); } public int EndWork() { if(null == et) { t hrow new Exception("调用EndWork前,需要先调用BeginWork"); } else { et.WaitOne(); return R; } } }
static void Main(string[] args) { Worker w = new Worker(); w.BeginWork(()=> { Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId, w.EndWork()); }); Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); }
上記のシミュレーション APM モデルでは、Thread と ManualResetEvent を使用しました。マルチスレッドと ManualResetEvent に慣れていない場合は、非同期プログラミングを使用してください。 C# これには必然的にマルチスレッドの知識が必要になりますが、Microsoft は Framework で多くのカプセル化を行ってきましたが、その本質を理解する必要があります。
上記でシミュレートした APM 非同期モデルが単純である理由は、C# の開発プロセス中に多くの優れた文法規則が導入されたためです。上記の例では、ラムダ式をさらに使用しました。匿名デリゲートとラムダ式に詳しくない場合は、以前の Bolg の「匿名デリゲートとラムダ式」を参照してください。上記には非常に多くの広告がありますが、標準の APM モデルが非同期プログラミングを実装する方法を見てみましょう。
IAsyncResultインターフェース
IAsyncResultインターフェースは、非同期関数のステータスを定義します。このインターフェースの具体的な属性と意味は次のとおりです:
// 表示异步操作的状态。 [ComVisible(true)] public interface IAsyncResult { // // 摘要: // 获取一个值,该值指示异步操作是否已完成。 // // 返回结果: // 如果操作已完成,则为 true;否则为 false。 bool IsCompleted { get; } // // 摘要: // 获取用于等待异步操作完成的 System.Threading.WaitHandle。 // // 返回结果: // 用于等待异步操作完成的 System.Threading.WaitHandle。 WaitHandle AsyncWaitHandle { get; } // // 摘要: // 获取一个用户定义的对象,该对象限定或包含有关异步操作的信息。 // // 返回结果: // 一个用户定义的对象,限定或包含有关异步操作的信息。 object AsyncState { get; } // // 摘要: // 获取一个值,该值指示异步操作是否同步完成。 // // 返回结果: // 如果异步操作同步完成,则为 true;否则为 false。 bool CompletedSynchronously { get; } }
注: モデル例1のManualResetEventは、WaitHandle<br/>APMの伝説的な実装メソッド<br/>を継承しています。 IAsyncResult インターフェイス 最後に、IAsyncResult インターフェイスを実装してシミュレーション サンプルの書き換えを完了します。 コードは次のとおりです。
public class NewWorker { public class WorkerAsyncResult : IAsyncResult { AsyncCallback callback; public WorkerAsyncResult(int a,int b, AsyncCallback callback, object asyncState) { A = a; B = b; state = asyncState; this.callback = callback; new Thread(Count).Start(this); } public int A { get; set; } public int B { get; set; } public int R { get; private set; } private object state; public object AsyncState { get { return state; } } private ManualResetEvent waitHandle; public WaitHandle AsyncWaitHandle { get { if (null == waitHandle) { waitHandle = new ManualResetEvent(false); } return waitHandle; } } private bool completedSynchronously; public bool CompletedSynchronously { get { return completedSynchronously; } } private bool isCompleted; public bool IsCompleted { get { return isCompleted; } } private static void Count(object state) { var result = state as WorkerAsyncResult; result.R = result.A + result.B; Thread.Sleep(1000); result.completedSynchronously = false; result.isCompleted = true; ((ManualResetEvent)result.AsyncWaitHandle).Set(); if (result.callback != null) { result.callback(result); } } } public int Num1 { get; set; } public int Num2 { get; set; } public IAsyncResult BeginWork(AsyncCallback userCallback, object asyncState) { IAsyncResult result = new WorkerAsyncResult(Num1,Num2,userCallback, asyncState); return result; } public int EndWork(IAsyncResult result) { WorkerAsyncResult r = result as WorkerAsyncResult; r.AsyncWaitHandle.WaitOne(); return r.R; } }
サンプル コード分析:
上記のコードの NewWorker の内部クラス WorkerAsyncResult が重要なポイントです。 IAsyncResult インターフェイスを実装し、それによって制御され、計算作業を完了するための新しいスレッドを開始します。
WorkerAsyncResult では、計算に使用される値を保存するために 2 つのプライベート属性 A と B が追加され、WorkerAsyncResult の内部操作の結果を保存するために、外部から読み取り可能で書き込み不可能な属性 R が使用されます。 AsyncWaitHandle プロパティは ManualResetEvent によって動作し、最初のアクセス時に ManualResetEvent が作成されます (ただし、解放されません)。他のインターフェースプロパティは通常通り実装されており、言うことはありません。
新しい静的 Count メソッドが WorkerAsyncResult に追加され、パラメーターの状態は Count メソッドを呼び出す現在の WorkerAsyncResult オブジェクトです。 Count メソッドは WorkerAsyncResult オブジェクトの新しく開始されたスレッドで実行されるため、Thread.Sleep(1000) は新しいスレッドを 1 秒間ブロックします。次に、現在の WorkerAsyncResult オブジェクトが同期的に完了したかどうかを false に設定し、ManualResetEvent 通知を解放して、スレッドが通知を取得して実行状態になるかどうかを確認します。存在する場合はコールバックします。
NewWorker は非常に単純で、Num1 と Num2 の 2 つの属性が計算対象の値です。 BeginWork は WorkerAsyncResult オブジェクトを作成し、計算対象の 2 つの値、Num1、Num2、userCallback コールバック デリゲート、およびオブジェクト型 asyncState を、作成される WorkerAsyncResult オブジェクトに渡します。この手順の後、WorkerAsyncResult オブジェクトは操作に必要なすべてのデータ、操作完了後のコールバックを取得し、操作を実行するための新しいスレッドをすぐに開始します (WorkerAsyncResult.Count メソッドを実行します)。
WorkerAsyncResult.Countは新規スレッドで実行されるため、スレッド外部では新規スレッドの状態を正確に知ることができません。外部スレッドが新しいスレッドと同期する必要があるため、EndWork メソッドが NewWorker に追加され、パラメーターの型は IAsyncResult です。 EndWork メソッドを呼び出すには、BeginWork によって取得された WorkerAsyncResult オブジェクトを渡す必要があります。EndWork メソッドが WorkerAsyncResult オブジェクトを取得した後、WorkerAsyncResult.AsyncWaitHandle.WaitOne() メソッドを呼び出し、通知が取得されるまで待ちます。操作スレッドが操作を完了した (スレッドが終了していない) 場合、次のステップは操作結果 R を取得して返します。
次のステップは、次のような NewWorker 呼び出しプログラムです:
static void Main(string[] args) { NewWorker w2 = new NewWorker(); w2.Num1 = 10; w2.Num2 = 12; IAsyncResult r = null; r = w2.BeginWork((obj) => { Console.WriteLine("Thread Id:{0},Count:{1}",Thread.CurrentThread.ManagedThreadId, w2.EndWork(r)); }, null); Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); }
下の図に単純に描いたプログラム呼び出しプロセスは、友人の理解に役立ちます:
開発者に対応した標準 APM モデルの非同期プログラミング複雑すぎると言いました。したがって、IAsyncResult インターフェースの実装による非同期プログラミングは、凡例のですが、役に立ちません (罪、罪、罪...)。
デリゲート非同期プログラミング (APM 標準実装)
C#中委托天生支持异步调用(APM模型),任何委托对象后"."就会发现BeginInvoke、EndInvoke、Invoke三个方法。BeginInvoke为异步方式调用委托、EndInvoke等待委托的异步调用结束、Invoke同步方式调用委托。因此上面的标准APM实例,可借助 delegate 进行如下简化。
上面NewWorker使用委托方式改写如下:
<br/>
<br/>
public class NewWorker2 { Func<int, int, int> action; public NewWorker2() { action = new Func<int, int, int>(Work); } public IAsyncResult BeginWork(AsyncCallback callback, object state) { dynamic obj = state; return action.BeginInvoke(obj.A, obj.B, callback, this); } public int EndWork(IAsyncResult asyncResult) { try { return action.EndInvoke(asyncResult); } catch (Exception ex) { throw ex; } } private int Work(int a, int b) { Thread.Sleep(1000); return a + b; } }
调用程序:
static void Main(string[] args) { NewWorker2 w2 = new NewWorker2(); IAsyncResult r = null; r = w2.BeginWork((obj) => { Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId, w2.EndWork(r)); }, new { A = 10, B = 11 }); Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); }
上面的使用委托进行APM异步编程,比实现 IAsyncResult 接口的方式精简太多、更易理解使用。因此这里建议朋友们 delegate 异步调用模型应该掌握起来,而通过实现 IAsyncResult 接口的传说方式看你的喜好吧。
以上がC# 非同期 APM モードの非同期プログラム開発例の共有の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









現在、人工知能(AI)技術の開発は本格化しており、さまざまな分野で大きな可能性と影響力を発揮しています。本日、Dayao は、参考にしていただけるよう、4 つの .NET オープン ソース AI モデル LLM 関連プロジェクト フレームワークを共有します。 https://github.com/YSGStudyHards/DotNetGuide/blob/main/docs/DotNet/DotNetProjectPicks.mdSemanticKernelSemanticKernel は、OpenAI、Azure などの大規模言語モデル (LLM) を統合するように設計されたオープン ソース ソフトウェア開発キット (SDK) です。

.NET 開発者は、高品質のソフトウェアを提供するために機能とパフォーマンスを最適化することの重要性を認識する必要があります。提供されたリソースを巧みに活用し、Web サイトの読み込み時間を短縮することで、ユーザーに快適なエクスペリエンスを提供するだけでなく、インフラストラクチャのコストも削減できます。

同時実行性の高いリクエスト処理の点では、.NETASP.NETCoreWebAPI は JavaSpringMVC よりも優れたパフォーマンスを発揮します。その理由としては、AOT の早期コンパイルにより起動時間が短縮され、開発者がオブジェクト メモリの割り当てと解放を行うため、より洗練されたメモリ管理が行われます。

開発効率を向上させるために新しい Web 開発フレームワークの使用を検討している場合は、Flight フレームワークを検討することをお勧めします。この記事では、Web アプリケーション フレームワークとして Flight Framework を選択する理由を検討し、Flight Framework を使用する利点をいくつか挙げます。まず、Flight フレームワークは非常に軽量で使いやすいフレームワークです。 Flight フレームワークは非常に理解しやすく、すぐに使い始めることができます。いくつかのコアコンポーネントしかないので、理解するのにあまり時間をかける必要はありません

Go 言語は、ネットワーク アプリケーション (Web サーバー、API、マイクロサービス)、コマンド ライン ツール (システム管理スクリプト、データ処理プログラム、テスト ツール)、同時実行アプリケーション (分散システム、メッセージ キュー、データ ストリーム ハンドラー)。

C#.NETインタビューの質問と回答には、基本的な知識、コアの概念、高度な使用が含まれます。 1)基本知識:C#は、Microsoftが開発したオブジェクト指向言語であり、主に.NETフレームワークで使用されています。 2)コアの概念:委任とイベントは動的な結合方法を可能にし、LINQは強力なクエリ関数を提供します。 3)高度な使用:非同期プログラミングは応答性を向上させ、式ツリーは動的コード構造に使用されます。

C#シニア開発者とのインタビューでは、非同期プログラミング、LINQ、.NETフレームワークの内部作業原則などのコア知識をマスターする必要があります。 1.非同期プログラミングは、非同期を通じて操作を簡素化し、アプリケーションの応答性を向上させるのを待ちます。 2.LinqはSQLスタイルでデータを操作し、パフォーマンスに注意を払います。 3.ネットフレームワークのCLRはメモリを管理し、ガベージコレクションに注意して使用する必要があります。
