使对象响应按钮点击事件

3
我正在寻找一种方法,使具有运行进程的对象能够响应Windows Forms按钮点击。这个实用程序中的所有内容都发生在单个“主”Windows应用程序表单上。
该进程正在处理文件夹中的一堆文件,我想在表单上放置一个“暂停”按钮。
我可以创建一个全局变量,通过按钮改变其状态,并且让对象检查变量的状态作为其过程的一部分。
但是我想编写更好的软件,我怀疑使用委托、事件或某种形式的监听器设计模式等更优雅的方式来实现。
你有什么想法吗?

您可以检查线程。 - Kuzgun
2个回答

1
最好的处理方法是将长时间运行的进程放在后台线程上。可以使用BackgroundWorker来实现,这是我在Windows应用程序中选择的类。为什么?因为当通过它报告进度(例如更改按钮状态)时,它会自动处理线程切换到UI线程。
以下是一个示例,说明它的工作原理。假设您有一个BackgroundWorker的私有类字段:
private BackgroundWorker _worker = new BackgroundWorker();

在构造函数中,我们需要设置一些东西:
_worker.WorkerReportsProgress = true;

_worker.DoWork += DoWork;
_worker.ProgressChanged += ProgressChanged;
_worker.RunWorkerCompleted += RunWorkerCompleted;

好的,现在设置处理程序:
private void DoWork(object sender, DoWorkEventArgs e)
{
    // do the work here
}

private void ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // e.UserState is a value that you can pass anything to
    // like a string for a status label

    // e.ProgressPercentage is an integer that you specify letting
    // this event know what step the process is at - this is well
    // used for a progress bar
}

private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // e.Result is a value that you can pass anything to
    // like a reference to an object with the finished product
    // or whatever makes sense in your case
}

最后,要运行后台进程,只需执行以下操作:

_worker.RunWorkerAsync();

当需要报告进度时,在DoWork处理程序中执行以下操作:

// NOTE: make sure to pass AT LEAST a value of 1 for the percentage
// or the event handler will NEVER fire. Further, someValue can be anything
// an instance of an object with data or just a string, or nothing for that
// matter - it's up to you
_worker.ReportProgress(1, someValue);

0
听起来你已经在正确的方向上了 - 你的后台任务是由BackgroundWorker调用的吗?这是保持GUI响应并在循环中暂停的方法。在你的后台工作者中,让它等待一个暂停event wait handle(直到用户点击暂停按钮才会被“设置”)。
像这样创建事件:
KeepWorking = new EventWaitHandle(true, EventResetMode.ManualReset);

在工作线程中执行以下操作:
while (KeepWorking.WaitOne())
{
    ...
}

对于您的暂停按钮,设置和取消事件:

KeepWorking.Reset(); // To pause it
KeepWorking.Set(); // To unpause it

我有一个指向源文件夹的类。该类具有“start”方法,调用循环,一次获取一个文件。在类内部,活动只是过程性的。我双击文本框以显示文件夹浏览器对话框。然后有一个启动按钮,实例化执行工作的类,并将源文件夹作为构造函数的参数传递给它。我将研究这种背景工作者调用方式。但是,即使转换为此,我仍在寻找优雅的、信号量式的方法来响应“暂停”按钮。 - Brian Wren
我相信EventWaitHandle是你正在寻找的优雅方式!它的工作方式类似于信号量,因为它是一个专为线程间等待而设计的可等待对象。 - noelicus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接