2つの関連概念があります。非同期プログラミングとマルチスレッドです。基本的には、「並行」または非同期で処理を行うには、新しいスレッドを作成するか、同じスレッドで非同期で動作させることができます。
どちらの方法でも、race conditionsを防ぐには、何らかの仕組みが必要です。次のようにWikipediaの記事から私は、競合状態が定義されているにリンク:
競合状態やレースの危険が出力順序に依存している電子、 ソフトウェアやその他のシステムの動作です か他の制御できない事象のタイミング。プログラマが意図した順序でイベント が発生しない場合、バグになります。
少数の人々がコメントで述べたように、あなたは、スレッドセーフであることが、標準のListクラスに依存することはできません - あなたが複数のスレッドからそれを更新している場合、すなわち、それは予期しない動作をする可能性があります。マイクロソフトでは、非同期または複数のスレッドから更新する場合に、予期したように動作する特別な「ビルトイン」コレクションクラス(System.Collections.Concurrent namespace)を提供しています。
よく文書化されたライブラリ(Microsoftの一般的にはドキュメントの中ではかなり良い)については、問題のクラスまたはメソッドがスレッドセーフであるかどうかを明示的に述べることがよくあります。例えば、System.Collections.Generic.Listためdocumentationで、それは次のように述べている:(Visual BasicではShared)
この型のpublic staticメンバーは、スレッド 安全です。どのインスタンスメンバーもスレッドセーフであるとは限りません。
非同期プログラミング(vs。マルチスレッド)、私の標準的なイラストは次のようなものです:10人のレストランがあるとします。ウェイターが来たら、彼が注文した最初の人は準備ができていません。しかし、他の9人はそうです。したがって、ウェイターは他の9人に注文を求め、元の人に戻ってくる。 (それは間違いなく、元の人が注文する準備ができているのを待つために2番目のウェイターを手に入れてしまうので、とにかく時間を節約することはできません)。これは、async/awaitが通常動作する方法です(例外的に、Thread.Run(...)のようなTask Parallelライブラリ呼び出しのいくつかは、実際には他のスレッドで実行されています - 例では2番目のウェイターを持ち込みます)どのドキュメントがどのドキュメントであるかをチェックします)。
基本的には、同じスレッド上で非同期に(または新しいスレッドを作成して)選択するのは、I/Oバインドの何かをしようとしているかどうかによって決まります。結果)またはCPUにバインドされています。
Ebayの結果を待つことを主目的としているのであれば、マルチスレッドを使用した場合のパフォーマンス上のメリットがほとんどない場合と同じスレッドで非同期で作業するほうがよいでしょう。私たちのアナロジーに戻って考えてみましょう。最初の男が注文する準備が整うのを待つために2番目のウェイターを連れて来ることは、ウェイターが彼に戻ってくるだけでは必ずしも良いことではありません。
私はこの構文が完全でない場合ので、私を許してIDEの前に座っていないんだけど、ここで何ができるかのおおよそのアイデアです:Products.Add`がうまくでき
public async Task GetResults(int[] productIDsToGet) {
var tasks = new List<Task>();
foreach (int productID in productIDsToGet) {
Task task = GetResultFromEbay(productID);
tasks.Add(task);
}
// Wait for all of the tasks to complete
await Task.WhenAll(tasks);
}
private async Task GetResultFromEbay(int productIdToGet) {
// Get result asynchronously from eBay
}
' *危険な*の場合、 'Products'は' List 'であり、スレッドセーフではありません。 –
CPUボトルネックがありますか?あなたのコードをプロファイリングして、あなたのプログラムで最も多くの時間を取っていることを確認しましたか? – Dismissile
私は彼らがあなたを助けるようなやり方で異なって動作するのではないかと疑います。あなたのプロセスはCPUバインドで、I/Oバウンドではないのですか? 1回のI/O操作ですべてのデータを戻すために、すべてのIDを1つのクエリに渡すことはできませんか? –