2016-07-03 18 views
1

でデリゲートメソッド名を呼び出すBackgroundWorkerが舞台裏で実行されているセットアップを試行し、各ステップを完了すると別のモーダルダイアログで進行状況を更新します。もちろん、問題は、BackgroundWorkerスレッドから進捗ダイアログを更新しようとすると、スレッド間の問題が発生することです。パラメーター

コード:

public partial class ProgressDialog : Form 
{ 
    public string Message 
    { 
     get 
     { 
      return lblMessage.Text; 
     } 
     set 
     { 
      if(lblMessage.InvokeRequired) 
      { 
       // *** not sure how to invoke this by passing the "value" parameter *** 
       // *** returns a TargetParameterCountException *** 
       // *** trying to pass "value" in results in "Method name expected" error *** 
       lblMessage.Invoke(new UpdateMessageDelegate(SetMessage)); 
      } 
     } 
    } 

    private delegate void UpdateMessageDelegate(string s); 

    private void SetMessage(string s) 
    { 
     lblMessage.Text = s; 
    } 
} 

私は無事でラベルのテキスト値を変更するにはどうすればよい:(問題のある行は***で囲まれたコメントがある)

public void StartProcess() 
{ 
    // dialog that shows a simple marquee progress bar and a message 
    ProgressDialog progress = new ProgressDialog("Starting operation..."); 

    // create background worker thread 
    BackgroundWorker bw = new BackgroundWorker(); 
    bw.WorkerSupportsCancellation = true; 
    bw.WorkerReportsProgress = true; 
    bw.DoWork += Bw_DoWork; 
    bw.RunWorkerCompleted += Bw_RunWorkerCompleted; 

    if(!bw.IsBusy) 
    { 
     bw.RunWorkerAsync(); 
     progress.ShowDialog(); 
    } 
} 

private void Bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker bw = sender as BackgroundWorker; 
    if(bw.CancellationPending) 
    { 
     e.Cancel = true; 
    } 
    else 
    { 
     // perform step 1 

     // *** this line generates cross-thread problems *** 
     progress.Message = "Performing step 2..."; 

     // etc... 
    } 
} 

そしてここでは、進行状況ダイアログのコードですsetメソッドと暗黙のvalueパラメータを使用していますか?

答えて

1

は、このようにそれを呼び出してみてください。

lblMessage.Invoke((Action)(() => SetMessage(value))); 

はその後もプライベート UpdateMessageDelegateデリゲートを作成しないようにすることができます。

+0

ああ、それは、おかげで仕事ができます。私もちょうどこの質問への答えになる、それを行う別の方法を見つけました。 –

1

はちょうどそれを行うための一つの方法が見つかりました:

public string Message 
{ 
    get 
    { 
     return lblMessage.Text; 
    } 
    set 
    { 
     if(lblMessage.InvokeRequired) 
     { 
      lblMessage.Invoke(new UpdateMessageDelegate(SetMessage), value); 
     } 
    } 
} 
関連する問題