2

質問:2つのBackgroundWorkerが値としてtrueを返したかどうか、どちらもtrueを返さなかったか、または1つだけが返したかを確認するための最良の方法は何ですか。

追加情報:

現在、2つのBackgroundWorkerが2つのSQL接続が有効かどうかを確認し、接続が正常に行われたかどうかに応じて値を返しています。

コードは次のとおりです。

private void btnTestSConnection_Click(object sender, EventArgs e)
        {
            BackgroundWorker work1 = new BackgroundWorker { WorkerSupportsCancellation = true };
            BackgroundWorker work2 = new BackgroundWorker { WorkerSupportsCancellation = true };
            work1.RunWorkerCompleted += (item, a) =>
            {
                //need to figure out this portion
            };
            work2.RunWorkerCompleted += (item, a) =>
            {
                //need to figure out this portion
            };

            work1.DoWork += doWork;
            work2.DoWork += doWork;

            SourceString.InitialCatalog = txtSSourceDatabase.Text;
            work1.RunWorkerAsync(SourceString.ConnectionString);
            SourceString.InitialCatalog = txtSSystemDatabase.Text;
            work2.RunWorkerAsync(SourceString.ConnectionString);
        }

DoWorkEventHandler doWork = (sender, e) =>
        {
            SqlConnection Connection;
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 1; (i <= 10); i++)
            {
                    try
                    {
                        using (Connection = new SqlConnection((string)e.Argument))
                        {
                            Connection.Open();
                        }
                        e.Result = true;
                    }
                    catch (SqlException c)
                    {
                        e.Result = false;
                    }
                }
        };
4

3 に答える 3

3

KeyValuePairを返すことができます。ここで、最初のブール値は使用されたワーカーを表し(work1の場合はtrue、work2の場合はfalse)、2番目のブール値は次のようにDoWorkメソッドの戻り値です。

work1.DoWork += doWork;
work2.DoWork += doWork;

work1.RunWorkerAsync(true);
work2.RunWorkerAsync(false);

private void doWork(s, e)
{
  var kvp = new KeyValuePair<bool, bool>;
  kvp.Key = e.Argument as bool; // this indicate which of the worker returned a value
  ...
  using (Connection = new SqlConnection((string)e.Argument))
  {
    Connection.Open();
  }
  kvp.Value = true; // this is the result of your connection test
  ...
  e.Result = kvp
};

これで、RunWorkerCompletedで、結果をKeyValuePairにキャストし、work1またはwork2のどちらかがどちらの値を返したかを取得できます。

b.RunWorkerCompleted += (item, a) =>
{
  var kvp = a.Result as KeyValuePair<bool, bool>;
  //kvp.Key == true mean this is the work1
  //kvp.Value is the SQL connection test
};
于 2012-09-27T15:15:16.127 に答える
1

volatileブール変数でキーワードを使用できます。スレッド内でその値を変更します。完了後または作業プロセスでいつでも確認できます

于 2012-09-27T16:19:05.763 に答える
1

待機ハンドルを使用して、各完了時にイベントをトリガーできます。

private void btnTestSConnection_Click(object sender, EventArgs e)
        {
            EventWaitHandle firstComplete = new EventWaitHandle(false, EventResetMode.ManualReset);
            EventWaitHandle secondComplete = new EventWaitHandle(false, EventResetMode.ManualReset);

                bool overallResult = false;

            BackgroundWorker work1 = new BackgroundWorker { WorkerSupportsCancellation = true };
            BackgroundWorker work2 = new BackgroundWorker { WorkerSupportsCancellation = true };
            work1.RunWorkerCompleted += (item, a) =>
            {
                firstComplete.Set();
                //need to figure out this portion
                overallResult &= a.Result 
            };
            work2.RunWorkerCompleted += (item, a) =>
            {
                secondComplete.Set();
                //need to figure out this portion
                overallResult &= a.Result 
            };

            work1.DoWork += doWork;
            work2.DoWork += doWork;

            SourceString.InitialCatalog = txtSSourceDatabase.Text;
            work1.RunWorkerAsync(SourceString.ConnectionString);
            SourceString.InitialCatalog = txtSSystemDatabase.Text;
            work2.RunWorkerAsync(SourceString.ConnectionString);

            // Wait on First will not go until set
            firstComplete.WaitOne();

            // Wait on second
            secondComplete.WaitOne();

            // Both now complete
            //Do what you need to now
        }

DoWorkEventHandler doWork = (sender, e) =>
        {
            SqlConnection Connection;
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 1; (i <= 10); i++)
            {
                    try
                    {
                        using (Connection = new SqlConnection((string)e.Argument))
                        {
                            Connection.Open();
                        }
                        e.Result = true;
                    }
                    catch (SqlException c)
                    {
                        e.Result = false;
                    }
                }
        };
于 2012-09-27T15:01:25.473 に答える