この記事では主にC#のThread、Task、Async/Await、IAsyncResultの関連知識を紹介します。一定の参考値があるので、以下のエディタで見てみましょう
非同期と言えば、Thread、Task、async/await、IAsyncResult、これらについて今日は順番にお話しましょう
1 .Thread
マルチスレッドの意味は、アプリケーション内で、より時間のかかる操作 (io、データベース操作 )、または応答を待機している操作 (WCF 通信など) は、メイン スレッドが実行されないように、バックグラウンド スレッドを個別に開いて実行できます。ブロックされた場合は続行できます。次に実行します。バックグラウンド スレッドが完了するまで待ってから、メイン スレッドに通知して、対応する操作を実行します
C# で新しいスレッドを開くのは比較的簡単です
static void Main(string[] args) { Console.WriteLine("主线程开始"); //IsBackground=true,将其设置为后台线程 Thread t = new Thread(Run) { IsBackground = true }; t.Start(); Console.WriteLine("主线程在做其他的事!"); //主线程结束,后台线程会自动结束,不管有没有执行完成 //Thread.Sleep(300); Thread.Sleep(1500); Console.WriteLine("主线程结束"); } static void Run() { Thread.Sleep(700); Console.WriteLine("这是后台线程调用"); }
以下に示すように、
バックグラウンドスレッドが開始されたことがわかります。その後、メインスレッドはバックグラウンドスレッドの実行終了を待たずに実行を続けました
1.1スレッドプール
想像してみてください。 Web サイトのバックグラウンドで HTTP リクエストを処理するなど、処理する必要があるタスクが多数ある場合、リクエストごとにバックグラウンド スレッドを作成する必要があるのは明らかです。これは明らかに不適切です。メモリが不足し、頻繁に作成プロセスが速度に深刻な影響を与える場合、スレッド プールは、タスクが存在するときに、作成されたスレッドを保存してスレッド プールを形成することです。処理対象のスレッド プールにアイドル状態のスレッドがある場合 (前のタスクの完了後、スレッドはリサイクルされず、アイドル状態に設定されます)、スレッド プール内のスレッド実行を直接呼び出します (たとえば、 asp.netの処理機構にあるApplicationオブジェクト)、
使用例:for (int i = 0; i < 10; i++) { ThreadPool.QueueUserWorkItem(m => { Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()); }); } Console.Read();実行結果:
1.2 セマフォ
セマフォはスレッドの調整を担当し、特定のリソースにアクセスするスレッドの数を制限できます 以下に SemaphoreSlim クラスの簡単な使用例を示します:static SemaphoreSlim semLim = new SemaphoreSlim(3); //3表示最多只能有三个线程同时访问 static void Main(string[] args) { for (int i = 0; i < 10; i++) { new Thread(SemaphoreTest).Start(); } Console.Read(); } static void SemaphoreTest() { semLim.Wait(); Console.WriteLine("线程" + Thread.CurrentThread.ManagedThreadId.ToString() + "开始执行"); Thread.Sleep(2000); Console.WriteLine("线程" + Thread.CurrentThread.ManagedThreadId.ToString() + "执行完毕"); semLim.Release(); }実行結果は次のとおりです。
ご覧のとおり、最初は 3 つのスレッドだけが実行され、1 つのスレッドが実行されて解放されると、新しいスレッドが実行されます。
タスクは .NET4.0 に追加されました。プール ThreadPool では、Task を使用して新しいタスクを開始すると、スレッドはスレッド プールから呼び出され、Thread はインスタンス化されるたびに新しいスレッドを作成します。
Console.WriteLine("主线程启动"); //Task.Run启动一个线程 //Task启动的是后台线程,要在主线程中等待后台线程执行完毕,可以调用Wait方法 //Task task = Task.Factory.StartNew(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); }); Task task = Task.Run(() => { Thread.Sleep(1500); Console.WriteLine("task启动"); }); Thread.Sleep(300); task.Wait(); Console.WriteLine("主线程结束");
実行結果は以下の通りです:
新しいタスクの開始方法: Task.Run() または Task.Factory.StartNew() でバックグラウンドスレッドが開始されるまで待つ必要があります。バックグラウンド スレッドの実行を完了するには、Wait メソッドを使用できます (同期的に実行されます)。 Wait がない場合は非同期で実行されます。タスクとスレッドの比較:
static void Main(string[] args) { for (int i = 0; i < 5; i++) { new Thread(Run1).Start(); } for (int i = 0; i < 5; i++) { Task.Run(() => { Run2(); }); } } static void Run1() { Console.WriteLine("Thread Id =" + Thread.CurrentThread.ManagedThreadId); } static void Run2() { Console.WriteLine("Task调用的Thread Id =" + Thread.CurrentThread.ManagedThreadId); }
実行結果:
Thread を直接使用すると 5 つのスレッドが開き、Task (スレッド プールを使用) を使用すると 3 つのスレッドが開くことがわかります。2.1 Task
TaskConsole.WriteLine("主线程开始");
//返回值类型为string
Task<string> task = Task<string>.Run(() => {
Thread.Sleep(2000);
return Thread.CurrentThread.ManagedThreadId.ToString();
});
//会等到task执行完毕才会输出;
Console.WriteLine(task.Result);
Console.WriteLine("主线程结束");
実行結果:
Task タスクは cancelTokenSource クラスを通じてキャンセルできますが、あまり使用されていないと思いますので、使用方法は比較的簡単です。興味がある方は検索してみてください。
async/await は C# 5.0 で導入されました。まず、メソッドを変更するために
static void Main(string[] args) { Console.WriteLine("-------主线程启动-------"); Task<int> task = GetStrLengthAsync(); Console.WriteLine("主线程继续执行"); Console.WriteLine("Task返回的值" + task.Result); Console.WriteLine("-------主线程结束-------"); } static async Task<int> GetStrLengthAsync() { Console.WriteLine("GetStrLengthAsync方法开始执行"); //此处返回的<string>中的字符串类型,而不是Task<string> string str = await GetString(); Console.WriteLine("GetStrLengthAsync方法执行结束"); return str.Length; } static Task<string> GetString() { //Console.WriteLine("GetString方法开始执行") return Task<string>.Run(() => { Thread.Sleep(2000); return "GetString的返回值"; }); }
async が使用され、メソッドが非同期であることを示し、宣言された戻り値の型が返されます。メソッドは void、Task、または Task await必须用来修饰Task或Task 看看运行结果: 可以看出来,main函数调用GetStrLengthAsync方法后,在await之前,都是同步执行的,直到遇到await关键字,main函数才返回继续执行。 那么是否是在遇到await关键字的时候程序自动开启了一个后台线程去执行GetString方法呢? 现在把GetString方法中的那行注释加上,运行的结果是: 大家可以看到,在遇到await关键字后,没有继续执行GetStrLengthAsync方法后面的操作,也没有马上反回到main函数中,而是执行了GetString的第一行,以此可以判断await这里并没有开启新的线程去执行GetString方法,而是以同步的方式让GetString方法执行,等到执行到GetString方法中的Task 那么await的作用是什么呢? 可以从字面上理解,上面提到task.wait可以让主线程等待后台线程执行完毕,await和wait类似,同样是等待,等待Task 那么await是怎么做到的呢?有没有开启新线程去等待? 只有两个线程(主线程和Task开启的线程)!至于怎么做到的(我也不知道......>_ 4.IAsyncResult IAsyncResult自.NET1.1起就有了,包含可异步操作的方法的类需要实现它,Task类就实现了该接口 在不借助于Task的情况下怎么实现异步呢? 关键步骤就是红色字体的部分,运行结果: 和Task的用法差异不是很大!result.AsyncWaitHandle.WaitOne()就类似Task的Wait。 5.Parallel 最后说一下在循环中开启多线程的简单方法: 运行结果: 循环Listclass Program
{
static void Main(string[] args)
{
Console.WriteLine("主程序开始--------------------");
int threadId;
AsyncDemo ad = new AsyncDemo();
AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);
IAsyncResult result = caller.BeginInvoke(3000,out threadId, null, null);
Thread.Sleep(0);
Console.WriteLine("主线程线程 {0} 正在运行.",Thread.CurrentThread.ManagedThreadId)
//会阻塞线程,直到后台线程执行完毕之后,才会往下执行
result.AsyncWaitHandle.WaitOne();
Console.WriteLine("主程序在做一些事情!!!");
//获取异步执行的结果
string returnValue = caller.EndInvoke(out threadId, result);
//释放资源
result.AsyncWaitHandle.Close();
Console.WriteLine("主程序结束--------------------");
Console.Read();
}
}
public class AsyncDemo
{
//供后台线程执行的方法
public string TestMethod(int callDuration, out int threadId)
{
Console.WriteLine("测试方法开始执行.");
Thread.Sleep(callDuration);
threadId = Thread.CurrentThread.ManagedThreadId;
return String.Format("测试方法执行的时间 {0}.", callDuration.ToString());
}
}
public delegate string AsyncMethodCaller(int callDuration, out int threadId);
Stopwatch watch1 = new Stopwatch();
watch1.Start();
for (int i = 1; i <= 10; i++)
{
Console.Write(i + ",");
Thread.Sleep(1000);
}
watch1.Stop();
Console.WriteLine(watch1.Elapsed);
Stopwatch watch2 = new Stopwatch();
watch2.Start();
//会调用线程池中的线程
Parallel.For(1, 11, i =>
{
Console.WriteLine(i + ",线程ID:" + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
});
watch2.Stop();
Console.WriteLine(watch2.Elapsed);
List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9 };
Parallel.ForEach<int>(list, n =>
{
Console.WriteLine(n);
Thread.Sleep(1000);
});
Action[] actions = new Action[] {
new Action(()=>{
Console.WriteLine("方法1");
}),
new Action(()=>{
Console.WriteLine("方法2");
})
};
Parallel.Invoke(actions);
以上がC#でのThread、Task、Async/Await、IAsyncResultのグラフィックコードの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

c#.netアプリをAzureまたはAWSに展開する方法は?答えは、AzureAppServiceとAwselasticBeanStalkを使用することです。 1。Azureでは、AzureAppServiceとAzurePipelinesを使用して展開を自動化します。 2。AWSでは、Amazon ElasticBeanstalkとAwslambdaを使用して、展開とサーバーレス計算を実装します。

C#と.NETの組み合わせにより、開発者に強力なプログラミング環境を提供します。 1)C#は、多型と非同期プログラミングをサポートします。2).NETは、クロスプラットフォーム機能と同時処理メカニズムを提供し、デスクトップ、Web、モバイルアプリケーション開発で広く使用されています。

.NetFrameworkはソフトウェアフレームワークであり、C#はプログラミング言語です。 1..netframeworkは、デスクトップ、Web、モバイルアプリケーションの開発をサポートするライブラリとサービスを提供します。 2.C#は.NetFrameWork用に設計されており、最新のプログラミング機能をサポートしています。 3..NetFrameworkはCLRを介してコード実行を管理し、C#コードはILにコンパイルされ、CLRによって実行されます。 4. .NetFrameWorkを使用してアプリケーションをすばやく開発し、C#はLINQなどの高度な関数を提供します。 5.一般的なエラーには、タイプ変換と非同期プログラミングデッドロックが含まれます。 VisualStudioツールは、デバッグに必要です。

C#は、Microsoftが開発した最新のオブジェクト指向プログラミング言語であり、.NETはMicrosoftが提供する開発フレームワークです。 C#は、CのパフォーマンスとJavaのシンプルさを組み合わせており、さまざまなアプリケーションの構築に適しています。 .NETフレームワークは、複数の言語をサポートし、ガベージコレクションメカニズムを提供し、メモリ管理を簡素化します。

C#と.NETランタイムは密接に連携して、開発者に効率的で強力なプラットフォームの開発機能に力を与えます。 1)C#は、.NETフレームワークとシームレスに統合するように設計されたタイプセーフおよびオブジェクト指向のプログラミング言語です。 2).NETランタイムは、C#コードの実行を管理し、ガベージコレクション、タイプの安全性、その他のサービスを提供し、効率的でクロスプラットフォームの操作を保証します。

C#.NET開発を開始するには、次のことが必要です。1。C#の基本的な知識と.NETフレームワークのコア概念を理解する。 2。変数、データ型、制御構造、関数、クラスの基本概念をマスターします。 3。LINQや非同期プログラミングなど、C#の高度な機能を学習します。 4.一般的なエラーのためのデバッグテクニックとパフォーマンス最適化方法に精通してください。これらの手順を使用すると、C#.NETの世界に徐々に浸透し、効率的なアプリケーションを書き込むことができます。

C#と.NETの関係は切り離せませんが、同じものではありません。 C#はプログラミング言語であり、.NETは開発プラットフォームです。 C#は、コードの書き込み、.NETの中間言語(IL)にコンパイルされ、.NET Runtime(CLR)によって実行されるために使用されます。

C#.NETは、複数のアプリケーション開発をサポートする強力なツールとライブラリを提供するため、依然として重要です。 1)C#は.NETフレームワークを組み合わせて、開発を効率的かつ便利にします。 2)C#のタイプの安全性とゴミ収集メカニズムは、その利点を高めます。 3).NETは、クロスプラットフォームの実行環境とリッチAPIを提供し、開発の柔軟性を向上させます。


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

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

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

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

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