2016-08-08 12 views
0

私はC#Taskとスレッドを初めて使用しています。C#タスクを更新する

私は以下のようなコードがあります: -

public void UpdateSales(object sender, EventArgs args) 
{ 
    Task.Run(() => 
    { 
    // Some code Create Collection ... 
    // Some code with business logic .. 


    // Below code is to update UI 
    // is it safe to update UI like below 

     saleDataGrid.Dispatcher.Invoke((Action) (() => 
           { 

            saleDataGrid.ItemsSource = currentCollection; 
            saleDataGrid.Items.Refresh(); 
           })); 

    }); 
} 

私はこのコードが正しいかどうかわからないが。私はどのような場合でもデッドロックが発生すると思いますか?

タスクからUIを更新するにはどうすればいいですか? を使用していません。UpdateSalesはサードパーティ製のライブラリのイベントハンドラです。

+2

通常、Dispatcherを呼び出して、特定のスレッドで呼び出す必要があるかどうかを確認するだけです。しかし、あなたのコードがデッドロックを引き起こさないと確信しています。 –

答えて

6

UpdateSalesはクリーナーソリューションは、このなり、UIスレッドで呼び出されると仮定すると、 、await will automatically resume on a captured context(この場合はUIコンテキスト)。私はDispatcherではなく、awaitという暗黙のコンテキストを直接使用するほうがはるかに好きです。コードは短く移植性が高いです。

+0

'UpdateSales'イベントがCOMオブジェクトイベントハンドラから起動しています。それがUIスレッドかどうかはわかりません。このメソッドシグネチャを正しく取得するために、このメソッドのシグネチャを編集しました。 –

5

ご存知のように、Task.Runはスレッドプールスレッドで実行されます。

あなたは、そのタスクの完了時に実行されますContinueWithを使用することができます - あなたはone of the overridesを選択した場合は、その後、あなたは上の方法を入力し、同期コンテキストを使用するどのTaskScheduler.FromCurrentSynchronizationContext()を使用することができますTaskSchedulerを指定できるように - それがUIスレッドの場合(たとえば、UIイベントのイベントハンドラにある場合)、同期コンテキストはUIスレッドのコンテキストになります。

だからあなたのコードは次のようになります。私は私のブログで説明したよう

public async void UpdateSales() 
{ 
    var collection = await Task.Run(() => 
    { 
    // Some code Create Collection ... 
    // Some code with business logic .. 
    return currentCollection; 
    }); 
    saleDataGrid.ItemsSource = collection; 
    saleDataGrid.Items.Refresh(); 
} 

Task.Run(() => { 
        ...code to create collection etc... 
       } 
     ) 
     .ContinueWith(() => { 
           saleDataGrid.ItemsSource = currentCollection; 
          } 
         , TaskScheduler.FromCurrentSynchronizationContext() 
        ); 
関連する問題