2016-08-31 7 views
0

私はBackgroundWorkerとスレッドを使用しています、アプリケーションは、このスレッドが完了するまで待つために、他の操作を50000レコードをフェッチするために長い時間待っています。セカンダリスレッドの使用中に待機プロセスを回避するにはどうすればよいですか。スレッドは、長い時間待つ。どのように私はこれを避けることができます

private void btnExrtPDF_Click(object sender, RoutedEventArgs e) 
{ 
    if (DetailsOrSummary == "Details") 
     isDetails = true; 

    Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() => 
    { 
     try 
     { 
      DetailReportFCBuySell = AlyexWCFService.DL.DLTTIn.FCBuySELL(
       transactionName, isDetails, 
       Convert.ToDateTime(dateEdtStartDate.EditValue).Date, 
       Convert.ToDateTime(dtpEditEndDate.EditValue).Date, 
       Customerid, ProductID, branchID, 
       NoOfRecords, PageIndex - 1, isBuy); 

      worker.RunWorkerAsync(); 
     } 
     catch 
     {    
      object obj = new object(); 
     } 
    })); 
} 

private void worker_DoWork(object sender, DoWorkEventArgs e) 
{   
    Dispatcher.Invoke(new Action(() => 
    { 
     System.Data.DataTable batchFCSB = new System.Data.DataTable(); 
     int row = 0; 

     if (DetailReportFCBuySell.FirstOrDefault().TotalRecords > toFetchRecords) 
     { 
      long RecordsIcrease = 1000; 
      batchFCSB = DetailReportFCBuySell.ToDataTable(); 
      //Collection.Add(row, batchFCSB); 
      row = 1; 
      PageIndex++; 

      for (long k = toFetchRecords; k < DetailReportFCBuySell.FirstOrDefault().TotalRecords; k = +toFetchRecords) 
      { 
       new AlxServiceClient().Using(channel => 
       { 
        ObservableCollection<DLReports.FCBuySellDetail> temp 
         = AlyexWCFService.DL.DLTTIn.FCBuySELL(
          transactionName, isDetails, 
          Convert.ToDateTime(dateEdtStartDate.EditValue).Date, 
          Convert.ToDateTime(dtpEditEndDate.EditValue).Date, 
          Customerid, ProductID, branchID, NoOfRecords, PageIndex - 1, isBuy); 

        DetailReportFCBuySell = DetailReportFCBuySell.Union(temp).ToObservableCollection(); 

        row++; 
        PageIndex++; 

       }); 
       toFetchRecords = toFetchRecords + RecordsIcrease; 
      } 
     } 
    }), DispatcherPriority.ContextIdle); 
} 
+1

UIコンポーネントの更新と観察可能なコレクションの操作がUIスレッドで行われていることを確認してください。現在、UIスレッドですべてを実行しています。 – WBuck

+0

私はすでにpblmを解決してくれました。 –

答えて

-1

バックグラウンドワーカーを使用する方法です。

Sample app

のWinFormに2つのボタンを追加します。

最初にbtnStartWorkerがバックグラウンドワーカーをトリガします。

btnStartWorkerは無効で、バックグラウンドワーカーは実行中ですが、btnOtherをクリックすることはできます。

public partial class Form1 : Form 
{ 
    private delegate void ReenableDelegate(); 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private BackgroundWorker worker; 
    private void btnStartWorker_Click(object sender, EventArgs e) 
    { 
     btnStartWorker.Enabled = false; 

     worker = new BackgroundWorker(); 
     worker.DoWork += Worker_DoWork; 
     worker.RunWorkerCompleted += Worker_RunWorkerCompleted; 
     worker.RunWorkerAsync(); 
    } 

    private void Worker_DoWork(object sender, DoWorkEventArgs e) 
    { 

     Thread.Sleep(5000); // simulate long running operation here 
    } 

    private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     this.Invoke(new ReenableDelegate(Enable)); 
    } 

    private void Enable() 
    { 
     btnStartWorker.Enabled = true; 
    } 

    private void btnOther_Click(object sender, EventArgs e) 
    { 
     MessageBox.Show("Doing other stuff"); 
    } 
} 
+0

1つのタスクだけではなく、このメソッドを試してみましたが、UIがしばらく待っています –

+0

あなたが待っていると言ったらブロックしていますか? – robor78

+0

、このスレッドが完了するまでUIは機能しません。このスレッドが並行して動作している間、私はUIを操作する必要があります –

1

コードは完全に間違っています。 Dispatcher.BeginInvoke()またはDispatcher.Invoke()への呼び出しのいずれも行うべきではありません。 BeginInvoke()への呼び出しは役に立たず、何も役に立たず、後者は実際にはすべての作業をUIスレッドで行いますが、バックグラウンドワーカースレッドではなくUIスレッドで行います。

BackgroundWorkerの代わりにawait Task.Run(...)のような近代的なアプローチを使用できます。そして、良いものがなければMinimal, Complete, and Verifiable code exampleより具体的な何かを提案することは不可能です。しかし、あなたが投稿したコードが今のところ立っているので、Dispatcherメソッドへのすべての呼び出しを削除して、呼び出されたコードを直接実行すると、期待どおりに動作するはずです。

+0

dispatchcherのすべての呼び出しを削除すると(「呼び出しスレッドはこのオブジェクトにアクセスできません」というメッセージが表示されます)。 (そしてもう1つは、私のアプリケーションでbackgroundworkerとスレッドを使用して初めてです。)stackoverflowから表示された例から、私はこれを多くしています。サー) –

+0

良い[mcve]がなければ、UIオブジェクトと何もないので、上記よりも具体的なアドバイスを提供することはできません。 UIオブジェクトにアクセスするときは、そうするためには 'Dispatcher.Invoke()'やそれに類するものを使う必要があります。しかし、残りのコードはバックグラウンドスレッドで動作する必要があります。 'Dispatcher.Invoke()'の呼び出しで_entire_タスクをラップすることは正しくなく、 'BackgroundWorker'を使用する点を完全に否定します。 –

+0

ここで質問した質問は、なぜあなたの 'BackgroundWorker'がUIスレッドをブロックしているのかということです。この問題を解決した後でも、UIオブジェクトを正しく更新する方法がわからない場合は、新しい質問を投稿してください。今回は問題を確実に再現する良い[mcve]を含めてください。 –

関連する問題