2017-05-24 21 views
-5

私はスレッドを選択したアプリケーションを持っています。この背後にある目的は、複数のスレッドを同時に実行してアプリケーションを高速化することです。C#スレッド非同期処理

現在、私はアプリケーション設定をループし、各設定のスレッドを作成し、それぞれを起動して、それらがすべて完了したときに通知します。

これを実行する際、各スレッドは同期して実行され、目的を破ります。

私は結合を削除するためにそれを変更することができましたが、すべてのスレッドが終了した時点を特定できません。(すべて完了した時点で実行する必要があります。

私はスレッディングが私のためではないと思っていますが、スレッディングタスクやparallel.foreachをもっと見なければなりませんが、どちらかの複雑さはわかりません。私は以下の

は現在、このスレッドを一つずつ実行し、最後の処理を実行する

現在
foreach (SettingsProperty value in Properties.Settings.Default.Properties) 
{ 
    //parse out the line in the settings 
    if (value.Name.ToString() != <<criteria>>) 
    { 
     //this is one that we want to do something with 
     sett = value.DefaultValue.ToString().Split(stringSeparators, StringSplitOptions.None); 

     //set the directory 
     Directory.CreateDirectory(<<directory>>); 

     //fire the thread to retrieve the image form the url 
     ThreadWithState tws = new ThreadWithState(<<parameters>>); 
     Thread t = new Thread(new ThreadStart(tws.ThreadProc)); 
     t.Start(); 
     t.Join(); 

    } 
} 
UploadFiles(); 

私のスレッドを生成コードスニペットであるメカニズムの前に(ともスレッドだけで手を出して)のいずれかを使用していません。 t.join呼び出しを削除すると、スレッド非同期が実行されますが、すべてのスレッドが完了する前にアップロードが実行されます。

どのように私はすべてのスレッドが終了するのを待つために、このコードを変更、または Parallel.ForEach(私は仕事かもしれないと思うが、全く理解していない)または は、いくつかのthreading.tasks機能を実装して実装することができますいずれかのように私(私も仕事かもしれないと思うが、全く理解していない)Task.WhenAll方法

+1

なぜあなたは 't.Join()'を呼び出していますか? –

+1

あなたの質問は広すぎます。並行して実行するには、有効な方法がたくさんあります。あなたのコードはそれらの方法のどれも試みません。先ほど起動したスレッドですぐに 'Join()'を呼び出すと、現在のスレッドが終了するまで別のスレッドを開始しません。別のスレッドを開始する前に待つ必要がない場合は、**しばらくお待ちください。 –

+4

あなたは、適切なツールが何であるかを知っていると言います - 非同期ワークフローを構築する - あなたはそれを行う方法がわかりません。だから*それをやる方法を学ぶ*。これはチュートリアルのサイトではありません。並列ワークフローと非同期ワークフローの両方に関するチュートリアルがたくさんあります。行く!このようなIOバインドされたタスクでは、まず非同期ワークフローについて学習します。複数のスレッドを含む必要はありません。 –

答えて

0

Thread.Join()は、他のスレッドがそのタスクを完了するまで(待機)をブロックするために、実行中のスレッドを指示し使用することができます。

だから、この

t.Start(); 
t.Join(); 

は文字通りタスクを開始し、それが終了するまで何もしないことを意味します。

Parallel.ForEachを使用する場合は、操作したいもののリストを作成することから始めます。例えば、

var properties = Properties.Settings.Default.Properties 
    .Where(property => Name != "whatever"); 

は今propertiesIEnumerable<SettingsProperty>ある - 列挙、またはループスルーすることができますコレクション。

は今、あなたはこれを行うことができます:

Parallel.ForEach(properties, (property) => 
    { 
     // do something with the property. 
    }); 

をこれは本質的にループの反復が並行スレッド上で実行することができることを除いて

foreach(var property in properties) 
{ 
    // do something with the property. 
} 

と同じです。タスクスケジューラは、ワークロードと利用可能なものに応じてスレッドを使用するため、「5月」になります。

-3

見た目から、複数の画像をWebサーバーから一度にダウンロードしようとしていますか?

私は一度にすべてのスレッドを開始します(現在は何をしていますが、thread.join()は含まれていません)。 foreachUploadFiles()の前)の後、すべてのスレッドが停止するまで、常にリストを繰り返し処理します。これにより、現在のタスク/ダウンロードが完了するまで実行をブロックするのではなく、すべてのタスクが完了するまで実行をブロックするという効果があります。

bool stillRunning = true; 
while(stillRunning) 
    stillRunning = false; 
    foreach(Thread thr in threadList) 
     if(thr.IsAlive) 
      stillRunning = true; 

UploadFiles(); 
+1

これは*恐ろしい*アドバイスなので、やってはいけません。まず、IOバインドされた作業を最初にワーカースレッドに割り当てる理由は何ですか?この作業はすべて* 1つのスレッドで行うことができます。第2に、複数のスレッドに作業を割り当てたい場合は、タスク並列ライブラリを使用して作業を割り当て、完了したらどうか調べるなどします。第3に、*スレッドがポーリングされているかどうかを調べる*。これは、最新のマルチスレッドオペレーティングシステムです。多くのスレッドが完了するのを待つ場合は、そうするための多くの*正しい*メカニズムがあります。 –

+0

フィードバックのおかげでエリック、私はこれが最適なソリューションから遠いことを認識し、提供されているさまざまなライブラリと言語機能を使用する必要があります。しかし、私は思考の列にも属しています。それは、最も速く、最も簡単なコードが、状況によっては最も効果的であると私に伝えています。いくつかの「正しい」メカニズムが存在して、いくつかのスレッドが完了したときを判断することができます。単純に反復的にポーリングするよりも優れていますか?私は別の方法についてあまり知らないので、コードを変更してブロックされないように答えました。 1つの問題に対する多くの解決策があります。 – TheWhoAreYouPerson

+1

*複数の制御スレッドを持つプログラムの正確な解析* - 解析が難しく、*生産性の低下を招き*有名になっている*プログラムは、正確にはコード化されていない*コード化するのが最速のものを何でもやって基本を理解する*。それがプログラミングに対するあなたの態度なら、その態度が有益な多くの種類のプログラミング作業があります。マルチスレッド制御フローは、その1つではありません。 –