2012-03-15 13 views
-2

可能性の重複:
Timing issue - DGV refreshes before process amends the dataルーチンをスレッドに分割するにはどうすればよいですか?

私は、次のコード

private void btRunReport_Click(object sender, EventArgs e){ 

    Process p = new Process(); 
    p.StartInfo.FileName = @"\\fileserve\department$\ReportScheduler_v3.exe"; 
    p.StartInfo.Arguments = "12"; 
    p.Start(); 
    p.WaitForExit(); 
    InitializeGridView(); 
} 

pはデータベーステーブルX. InitializeGridViewがテーブルを反映DGVを更新更新されますを持っていますX.

問題は、pが10分かかると、winFormがInitializeGridView()に達する前にフリーズされているということです。私が助けが必要なのは、フォームの背後で動作し、InitializeGridView()を実行する別々のスレッドでフォームを開始するにはどうすればいいですか?

+0

スレッドをプロセスの先頭に戻すことはできません。プロセスを開始するスレッドを起動することは意味がありません。 p.WairForExitを持っていなかった場合、コードはInitializeGridView()に引き続き続きます。すぐに。 –

+0

C#4.0の[Threading in C#](http://www.albahari.com/threading/)を簡単に読んでみてください。あなたがやろうとしていることはほとんど簡単です。 **編集**:あなたがexeを実行しようとしていたという事実を見逃していました。それは良い記事です – akiller

+0

私はこれを行い、安全なキャンセルを容易にする唯一の方法は、別個のAppDomainを使用することだと思っています... – MoonKnight

答えて

1

あなたは、プロセスが終了した後に実行するためにあなたのInitialilzeGridView()メソッドが必要な場合:

  1. を_currentDispatcherとして利用できるDispatcher.CurrentDispatcherしてください。
  2. プロセスを別のスレッドで開始し、そこにWaitForExit()を持ってください。
  3. スレッドをInitializeGridview()メソッド_currentDispatcher.BeginInvoke経由で呼び出してください。

    注:あなたは、プロジェクトの[参照の追加]ダイアログを経由してWindowsBaseへの参照を追加する必要があります

は、ここであなたが軌道に乗るためにいくつかのコードです。

using System; 
using System.Diagnostics; 
using System.Threading; 
using System.Windows.Forms; 
using System.Windows.Threading; 

private readonly Dispatcher _currentDispatcher = Dispatcher.CurrentDispatcher; 
private delegate void ReportingSchedulerFinishedDelegate(); 

private void btRunReport_Click(object sender, EventArgs e) 
{ 
    btRunReport.Enabled = false; 
    btRunReport.Text = "Processing.."; 
    var thread = new Thread(RunReportScheduler); 
    thread.Start(); 
} 

private void InitializeGridView() 
{ 
    // Whatever you need to do here 
} 

private void RunReportScheduler() 
{ 
    Process p = new Process(); 
    p.StartInfo.FileName = @"\\fileserve\department$\ReportScheduler_v3.exe"; 
    p.StartInfo.Arguments = "12"; 
    p.Start(); 
    p.WaitForExit(); 
    _currentDispatcher.BeginInvoke(new ReportingSchedulerFinishedDelegate(ReportingSchedulerFinished), DispatcherPriority.Normal); 
} 

private void ReportingSchedulerFinished() 
{ 
    InitializeGridView(); 
    btRunReport.Enabled = true; 
    btRunReport.Text = "Start"; 
} 
+0

あなたのソリューションは完全に動作するようです - 私はそれが今の動作を調べるためにそれを調べる必要があります! – whytheq

+0

これはかなり簡単です:長時間実行しているRunReportScheduleを独自のスレッドで実行します。バックグラウンドスレッドの問題は、メインのGUIスレッドが直接処理する要素に直接アクセスできないことです。 _currentDispatcherは、GUIスレッドからディスパッチャへの参照を保持し、データの準備が完了した後、代理人を介してReportSchedulerFinishedを実行するための指示を渡すことができます。 – Till

関連する問題