Я новичок в C # и объектно-ориентированном программировании в целом. Я пытался внедрить кнопку «Отмена» в мой графический интерфейс, чтобы пользователь мог остановить его в середине процесса.
Я прочитал этот вопрос: Как реализовать кнопку Стоп / Отмена? и определил, что backgroundWorker должен быть хорошим вариантом для меня, но в приведенном примере не объясняется, как передать аргументы в BackgroundWorker.
Моя проблема в том, что я не знаю, как передать аргумент в backgroundWorker, чтобы он остановил процесс; Я только смог заставить backgroundWorker остановить себя.
Я создал следующий код, чтобы попытаться узнать это, где моя форма имеет две кнопки (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.
}
}
}
Код, если он работал должным образом, просто сидел бы там в течение пяти секунд после нажатия пользователем кнопки «Пуск» перед повторным включением кнопки «Пуск» или быстро активировал бы кнопку «Пуск», если пользователь нажал «Стоп».
Есть две проблемы с этим кодом, которые я не знаю, как с ними справиться:
1) Метод «myTimer_Elapsed» приводит к возникновению исключения InvalidOperationException при попытке включить кнопку «Пуск», поскольку «операция с несколькими потоками была недопустимой». Как избежать операций с несколькими потоками?
2) Сейчас backgroundWorker ничего не выполняет, потому что я не знаю, как передать ему аргументы, чтобы при отмене он остановил таймер.
Буду признателен за любую помощь!