C# 如何实现停止/取消按钮?

C# 如何实现停止/取消按钮?,c#,.net,winforms,visual-studio-2010,cancel-button,C#,.net,Winforms,Visual Studio 2010,Cancel Button,我有一个processData()方法,它接受大量数据并对其进行一些处理。有一个开始按钮启动处理。我需要一个“取消”按钮,它可以在任何地方停止处理。我如何实现这样的功能?我不明白的是,一旦处理开始,如何使cancel按钮可用,因为当函数运行时,UI的其余部分被冻结 将重码放入DoWork事件中 取消按钮应在BackgroundWorker上调用CancelAsync 在DoWork中的heacy代码中,定期检查CancellationPending属性。如果属性为true,则应中止该工作。方法是

我有一个processData()方法,它接受大量数据并对其进行一些处理。有一个开始按钮启动处理。我需要一个“取消”按钮,它可以在任何地方停止处理。我如何实现这样的功能?我不明白的是,一旦处理开始,如何使cancel按钮可用,因为当函数运行时,UI的其余部分被冻结

将重码放入
DoWork
事件中

取消按钮应在
BackgroundWorker
上调用
CancelAsync

DoWork
中的heacy代码中,定期检查
CancellationPending
属性。如果属性为
true
,则应中止该工作。

方法是您所需要的。这对你来说是个很好的例子

如果你有一个耗时的进程,你将不得不使用一个单独的线程来处理,以支持取消。如果您在主线程(UI线程)中执行这个耗时的进程,它将很忙,并且在完成该任务之前不会考虑您的取消请求。这就是为什么你会经历UI冻结

如果您将backgroundWorker用于耗时的任务,并且如果您在backgroundWorker.DoWork方法中选中CancellationPending标志,则可以实现您想要的

using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  

namespace BackgroundWorker  
{  
    public partial class Form1 : Form  
    {  
        public Form1()  
        {  
            InitializeComponent();  

            //mandatory. Otherwise will throw an exception when calling ReportProgress method  
            backgroundWorker1.WorkerReportsProgress = true;   

            //mandatory. Otherwise we would get an InvalidOperationException when trying to cancel the operation  
            backgroundWorker1.WorkerSupportsCancellation = true;  
        }  

        //This method is executed in a separate thread created by the background worker.  
        //so don't try to access any UI controls here!! (unless you use a delegate to do it)  
        //this attribute will prevent the debugger to stop here if any exception is raised.  
        //[System.Diagnostics.DebuggerNonUserCodeAttribute()]  
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)  
        {  
            //NOTE: we shouldn't use a try catch block here (unless you rethrow the exception)  
            //the backgroundworker will be able to detect any exception on this code.  
            //if any exception is produced, it will be available to you on   
            //the RunWorkerCompletedEventArgs object, method backgroundWorker1_RunWorkerCompleted  
            //try  
            //{  
                DateTime start = DateTime.Now;  
                e.Result = "";  
                for (int i = 0; i < 100; i++)  
                {  
                    System.Threading.Thread.Sleep(50); //do some intense task here.  
                    backgroundWorker1.ReportProgress(i, DateTime.Now); //notify progress to main thread. We also pass time information in UserState to cover this property in the example.  
                    //Error handling: uncomment this code if you want to test how an exception is handled by the background worker.  
                    //also uncomment the mentioned attribute above to it doesn't stop in the debugger.  
                    //if (i == 34)  
                    //    throw new Exception("something wrong here!!");  

                    //if cancellation is pending, cancel work.  
                    if (backgroundWorker1.CancellationPending)  
                    {  
                        e.Cancel = true;   
                        return;  
                    }  
                }  

                TimeSpan duration = DateTime.Now - start;  

                //we could return some useful information here, like calculation output, number of items affected, etc.. to the main thread.  
                e.Result = "Duration: " + duration.TotalMilliseconds.ToString() + " ms.";  
            //}  
            //catch(Exception ex){  
            //    MessageBox.Show("Don't use try catch here, let the backgroundworker handle it for you!");  
            //}  
        }  

        //This event is raised on the main thread.  
        //It is safe to access UI controls here.  
        private void backgroundWorker1_ProgressChanged(object sender,   
            ProgressChangedEventArgs e)  
        {  
            progressBar1.Value = e.ProgressPercentage; //update progress bar  

            DateTime time = Convert.ToDateTime(e.UserState); //get additional information about progress  

            //in this example, we log that optional additional info to textbox  
            txtOutput.AppendText(time.ToLongTimeString());  
            txtOutput.AppendText(Environment.NewLine);              
        }  

        //This is executed after the task is complete whatever the task has completed: a) sucessfully, b) with error c)has been cancelled  
        private void backgroundWorker1_RunWorkerCompleted(object sender,   
            RunWorkerCompletedEventArgs e)  
        {  
            if (e.Cancelled) {  
                MessageBox.Show("The task has been cancelled");  
            }  
            else if (e.Error != null)  
            {                  
                MessageBox.Show("Error. Details: " + (e.Error as Exception).ToString());  
            }  
            else {  
                MessageBox.Show("The task has been completed. Results: " + e.Result.ToString());  
            }  

        }  

        private void btoCancel_Click(object sender, EventArgs e)  
        {  
            //notify background worker we want to cancel the operation.  
            //this code doesn't actually cancel or kill the thread that is executing the job.  
            backgroundWorker1.CancelAsync();  
        }  

        private void btoStart_Click(object sender, EventArgs e)  
        {  
            backgroundWorker1.RunWorkerAsync();  
        }  
    }  
}  
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用系统文本;
使用System.Windows.Forms;
命名空间后台工作程序
{  
公共部分类Form1:Form
{  
公共表格1()
{  
初始化组件();
//必需。否则,将在调用ReportProgress方法时引发异常
backgroundWorker1.WorkerReportsProgress=true;
//必须。否则,在尝试取消操作时,我们将获得InvalidOperationException
backgroundWorker1.WorkerSupportsScanCellation=true;
}  
//此方法在后台工作程序创建的单独线程中执行。
//因此,不要尝试访问此处的任何UI控件!!(除非您使用委托进行访问)
//如果引发任何异常,此属性将阻止调试器在此停止。
//[System.Diagnostics.DebuggerNonUserCodeAttribute()]
私有void backgroundWorker1\u DoWork(对象发送方,DoWorkEventArgs e)
{  
//注意:此处不应使用try-catch块(除非重新显示异常)
//backgroundworker将能够检测到此代码上的任何异常。
//如果产生任何异常,您可以在
//RunWorkerCompletedEventArgs对象、方法backgroundWorker1\u RunWorkerCompleted
//试一试
//{  
DateTime start=DateTime.Now;
e、 结果=”;
对于(int i=0;i<100;i++)
{  
System.Threading.Thread.Sleep(50);//在这里执行一些高强度的任务。
backgroundWorker1.ReportProgress(i,DateTime.Now);//将进度通知主线程。我们还在UserState中传递时间信息,以涵盖示例中的此属性。
//错误处理:如果要测试后台工作程序如何处理异常,请取消对该代码的注释。
//另外,取消对上述属性的注释,使其不会在调试器中停止。
//如果(i==34)
//抛出新异常(“这里有问题!!”;
//如果取消挂起,请取消工作。
if(backgroundWorker1.CancellationPending)
{  
e、 取消=真;
返回;
}  
}  
TimeSpan duration=DateTime.Now-开始;
//我们可以在这里向主线程返回一些有用的信息,如计算输出、受影响的项目数等。
e、 Result=“Duration:”+Duration.total毫秒.ToString()+“ms.”;
//}  
//捕获(例外情况除外){
//Show(“不要在这里使用try-catch,让backgroundworker为您处理它!”);
//}  
}  
//此事件在主线程上引发。
//在这里访问UI控件是安全的。
私有void backgroundWorker1\u ProgressChanged(对象发送方,
ProgressChangedEventArgs(e)
{  
progressBar1.Value=e.ProgressPercentage;//更新进度条
DateTime=Convert.ToDateTime(e.UserState);//获取有关进度的其他信息
//在本例中,我们将可选的附加信息记录到textbox
AppendText(time.ToLongTimeString());
AppendText(Environment.NewLine);
}  
//无论任务完成了什么,都会在任务完成后执行:a)成功,b)出现错误c)已取消
私有void backgroundWorker1\u RunWorkerCompleted(对象发送方,
RunWorkerCompletedEventArgs(e)
{  
如果(e)取消{
MessageBox.Show(“任务已被取消”);
}  
否则如果(例如错误!=null)
{                  
Show(“Error.Details:+(例如,Error作为异常).ToString());
}  
否则{
Show(“任务已完成。结果:+e.Result.ToString());
}  
}  
私有void b取消单击(对象发送者,事件参数e)
{  
//通知后台工作人员我们要取消操作。
/