2017-06-19 16 views
-1

この関数をライブラリで作成しました。私は、コンソールとWPFの両方のアプリケーションにこの機能を使用します。私のコンソールアプリケーションでは、この機能は1秒もかからずに完了し、最大80個のアイテムと小さなコレクションなどの大量収集が可能です。 5.WPFで非同期関数を高速化する方法

さらに、私のWPFアプリケーションでは、アイテムのコレクションを80個まで実行すると、実行を終了するのに1分以上かかりますが、5個までのアイテムは1秒未満で終了します。

C#コード:

public async Task<Dictionary<string, string[]>> GetTemplates(string showName) 
{ 
    Dictionary<string, string[]> d = new Dictionary<string, string[]>(); 

    // Get element collection uri of show "DemoShow" 
    var elementCollectionUriTask = Task.Run(() => GetElementCollectionUri(vizServiceDocURL, showName)); 
    var elementCollectionUri = await elementCollectionUriTask; 

    var templateCollectionUriTask = Task.Run(() => GetTemplateCollectionUri(elementCollectionUri)); 
    var templateCollectionUri = await templateCollectionUriTask; 

    var templateNamesTask = Task.Run(() => GetListOfTemplateName(templateCollectionUri)); 
    var templateNames = await templateNamesTask; 

    //get the name and links from each show and add them to the dictionary 
    foreach (string templateName in templateNames) 
    { 
     var templateCollectionEntryUriTask = Task.Run(() => GetTemplateCollectionEntryUri(templateCollectionUri, templateName)); 
     var templateCollectionEntryUri = await templateCollectionEntryUriTask; 

     var elementModelUriTask = Task.Run(() => GetTemplateElementModelUri(templateCollectionUri, templateName)); 
     var elementModelUri = await elementModelUriTask; 

     await Task.Run(() => PrintVdfModel(elementModelUri)); 

     string[] links = new string[2] { templateCollectionEntryUri, elementModelUri }; 
     d.Add(templateName, links); 
    } 
    return d; 
} 
+6

あなたが作業中にメソッド呼び出しをスピンアップし、主に同期とシーケンシャルに見える方法のために必要以上のオーバーヘッドが追加され、すぐにそれらを待っている、タスクで実行すると、物事をスピードアップしようとしていることを考えています。あなたのforeachループは、タスクとしてタスクをスピンアップさせ、リストにそれらのタスクを追加して、ループの外側で 'await Task.WhenAll(listOfTasks); 'ですべて待機するか、** Parallel.ForEach'を使用することができます** **ブロック操作**。 – ColinM

+2

@ColinMに同意すると、スレッドプール上で最大80 * 2の本質的に連続した操作をスケジュールしています。それらはお互いに待たなければならない可能性が高い場所です。順番に作業をするか、待っている同期メソッドの真の非同期バージョンを書くだけです。 – Clay

答えて

0

私のコメントで述べたように、あなたはこれらのジョブの処理を高速化したいならば、あなたは確かにロジックがパラレルに適用され、ループ上の作業のビットを行うことができますすべてのテンプレート名に適用されます。

public async Task<Dictionary<string, string[]>> GetTemplates(string showName) 
{ 
    Dictionary<string, string[]> d = new Dictionary<string, string[]>(); 

    // Get element collection uri of show "DemoShow" 
    var elementCollectionUri = GetElementCollectionUri(vizServiceDocURL, showName); 

    var templateCollectionUri = GetTemplateCollectionUri(elementCollectionUri); 

    var templateNames = GetListOfTemplateName(templateCollectionUri); 

    //get the name and links from each show and add them to the dictionary 
    // Keep a temporary List of Tasks 
    List<Task> allTasks = new List<Task>(); 
    foreach (string templateName in templateNames) 
    { 
     string localTemplateName = templateName; 
     // Apply our logic and add to our Dictionary in a task 
     Task jobTask = Task.Run(() => 
     { 
      var templateCollectionEntryUri = GetTemplateCollectionEntryUri(templateCollectionUri, localTemplateName); 

      var elementModelUri = GetTemplateElementModelUri(templateCollectionUri, localTemplateName); 

      string[] links = new string[2] { templateCollectionEntryUri, elementModelUri }; 
      d.Add(localTemplateName, links); 
     }); 

     // Add the task to our temp collection 
     allTasks.Add(jobTask); 
    } 

    // Wait for all tasks to finish, WhenAll is non-blocking unlike WaitAll. 
    await Task.WhenAll(allTasks); 

    return d; 
} 
+0

実行時間はまだ1分以上です。私はそれを呼び出す方法かもしれない? – Decoder94

+1

残りのコードは表示されず、WPFアプリケーションでのみ発生している場合は、コードの残りの部分は表示されません(つまり、パフォーマンスのプロファイリングをお勧めし、大半の時間が費やされている場所を見ています。 – ColinM

+0

ありがとう!私はパフォーマンスプロファイリングを見ていきます。私が最小限のコードで新しいWPFアプリケーションを作成したときには他のコードはありません。だから私はボタンを追加し、以前のコメントのコードでこのメソッドを呼び出し、ブレークポイントを関数の最後に置いています。 – Decoder94

関連する問題