私は一般的にC#とオブジェクト指向プログラミングに不慣れです。ユーザーがプロセスの途中で停止できるように、GUIに「キャンセル」ボタンを実装しようとしています。
私はこの質問を読みました:停止/キャンセルボタンを実装する方法は?そして、backgroundWorkerは私にとって良いオプションであると判断しましたが、与えられた例では、backgroundWorkerに引数を渡す方法を説明していません。
私の問題は、プロセスを停止するように引数をbackgroundWorkerに渡す方法がわからないことです。私はbackgroundWorkerを停止させることしかできませんでした。
これを学習するために、次のコードを作成しました。フォームには2つのボタン(buttonStartとbuttonStop)とbackgroundWorker(backgroundWorkerStopCheck)があります。
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;
using System.Timers;
namespace TestBackgroundWorker
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Set the background worker to allow the user to stop the process.
backgroundWorkerStopCheck.WorkerSupportsCancellation = true;
}
private System.Timers.Timer myTimer;
private void backgroundWorkerStopCheck_DoWork(object sender, DoWorkEventArgs e)
{
//If cancellation is pending, cancel work.
if (backgroundWorkerStopCheck.CancellationPending)
{
e.Cancel = true;
return;
}
}
private void buttonStart_Click(object sender, EventArgs e)
{
// Notify the backgroundWorker that the process is starting.
backgroundWorkerStopCheck.RunWorkerAsync();
LaunchCode();
}
private void buttonStop_Click(object sender, EventArgs e)
{
// Tell the backgroundWorker to stop process.
backgroundWorkerStopCheck.CancelAsync();
}
private void LaunchCode()
{
buttonStart.Enabled = false; // Disable the start button to show that the process is ongoing.
myTimer = new System.Timers.Timer(5000); // Waste five seconds.
myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
myTimer.Enabled = true; // Start the timer.
}
void myTimer_Elapsed(object sender, ElapsedEventArgs e)
{
buttonStart.Enabled = true; // ReEnable the Start button to show that the process either finished or was cancelled.
}
}
}
コードが正しく機能していれば、ユーザーが[スタート]をクリックしてから5秒間そこに留まり、[スタート]ボタンを再度有効にするか、ユーザーが[停止]をクリックするとすぐに[スタート]ボタンが再度アクティブになります。
このコードには、処理方法がわからない2つの問題があります。
1)「myTimer_Elapsed」メソッドは、「クロススレッド操作が無効でした」ため、[スタート]ボタンを有効にしようとするとInvalidOperationExceptionが発生します。クロススレッド操作を回避するにはどうすればよいですか?
2)現在、backgroundWorkerは、キャンセルされたときにタイマーを停止するように引数をフィードする方法がわからないため、何も実行しません。
助けていただければ幸いです!