0

WinForms アプリで実行する処理負荷の高いタスクがいくつかあります。問題は、実行中に UI (UI メインスレッド) がフリーズすることです。

私はまだ C# でスレッドとデリゲートをあまり扱っていません。そのため、ユーザーがアプリがクラッシュしていると思わないように、UI をフリーズせずにこれらのプロセスの重いタスクを処理する方法を誰かが助けてくれることを願っています。待ちながら?

例えば。を介して電話がありますが、FrontController時間がかかります:

_controller.testExportExcel(wrapper, saveDialog.FileName);

Excelファイルを作成しているためです。アプリが動作している間、UI で応答することはありません。

プロセス負荷の高いタスクの別の例は次のとおりです。

private void dataGridView_liste_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
  if (e.ListChangedType != ListChangedType.ItemDeleted)
  {
     foreach (DataGridViewRow r in dataGridView_liste.Rows)
     {
       DataGridViewCellStyle red = dataGridView_liste.DefaultCellStyle.Clone();
       red.BackColor = Color.LightGreen;
       if (r.Cells["News"].Value != null && (bool)r.Cells["News"].Value == true)
         r.DefaultCellStyle = red;
     }
  }
}

foreachループに時間がかかる場所で、UI をフリーズします。プロセスを実行し、完了すると自動的に閉じる非同期スレッドが役立つと思います。しかし、それはどのように機能しますか??

4

3 に答える 3

3

タスクを使用するのはどうですか(.net 4をターゲットにしている場合)?これは、ネスト(親/子タスク)、タスク継続などをサポートするため、BackgroundWorkerクラスの代わりと見なされます。

例えば

    private void dataGridView_liste_DataBindingComplete(object sender,
      DataGridViewBindingCompleteEventArgs e)  
    {
        Task t = Task.Factory.StartNew(() =>
        {
            // do your processing here - remember to call Invoke or BeginInvoke if
            // calling a UI object.
        });
        t.ContinueWith((Success) =>
        {
            // callback when task is complete.
        }, TaskContinuationOptions.NotOnFaulted);
        t.ContinueWith((Fail) =>
        {
            //log the exception i.e.: Fail.Exception.InnerException);
        }, TaskContinuationOptions.OnlyOnFaulted);

    }
于 2012-09-27T15:15:41.503 に答える
0

最初の例では、UI の応答性を維持するという要件を満たすには_controller.testExportExcel()、 、 aBackgroundWorkerまたはTask Parallel Library呼び出し (つまり) の呼び出しが適切です。Task.Factory.StartNew(...)ここにある他の回答を含め、たくさんの例が浮かんでいます。

2 番目の例では、UI を操作するコードのように見えるため、これをバックグラウンド スレッドに配置できないことがわかります。具体的には、BackgroundWorkerDoWorkイベント ハンドラーの実装、または に渡すデリゲートTask.Factory.StartNew()、または単純な古いスレッドのメソッドが UI に触れる場合、"クロススレッド操作有効ではありません"。

この理由は、この質問で説明されています。しかし、実際には、これは非同期にしたいほど遅いことにもっと驚いています。Control.SuspendLayout()このコードの応答性を高める簡単な方法がいくつかあるかもしれません.ResumeLayout()

于 2012-09-27T15:32:14.813 に答える