C# 如何在Windows窗体应用程序中重新启动backgroundworker?

C# 如何在Windows窗体应用程序中重新启动backgroundworker?,c#,.net,backgroundworker,C#,.net,Backgroundworker,我的代码的基本功能是允许用户浏览包含大量文件的文件夹,当用户单击“开始”按钮时,一个代码会使文件夹中的文件具有相同的名称和不同的扩展名。我想做的是添加一个“取消”按钮,这样,如果用户在一个不正确的文件夹上单击“开始”按钮,例如,用户可以取消,浏览到正确的文件夹,然后重新启动操作。 这是单击“开始”按钮时激发的代码: class ExcelCode { public static void DoExcel (string FolderPath) { System.I

我的代码的基本功能是允许用户浏览包含大量文件的文件夹,当用户单击“开始”按钮时,一个代码会使文件夹中的文件具有相同的名称和不同的扩展名。我想做的是添加一个“取消”按钮,这样,如果用户在一个不正确的文件夹上单击“开始”按钮,例如,用户可以取消,浏览到正确的文件夹,然后重新启动操作。 这是单击“开始”按钮时激发的代码:

class ExcelCode
{
    public static void DoExcel (string FolderPath)
    {
        System.IO.StreamWriter file = new System.IO.StreamWriter(FolderPath + ".fdf");
        Thread.Sleep(1000);
    }
}
经过数小时的研究,我一直尝试使用
backgroundworker.CancelAsync()和一个跟踪取消的全局变量,即DoWork()方法如下所示:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        if(backgroundWorker1.IsBusy)
        for (int i = 0; i < 100; i++)
        {
            foreach (string file in filePaths)
            {
                if(backgroundWorker1.CancellationPending)
                {
                    e.Cancel = true;
                    restartWorker = true;
                    return;
                }
                ExcelCode.DoExcel(file);
                //write to textbox
            }
            backgroundWorker1.ReportProgress(i);
        }
    }
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled && restartWorker)
        {
            if (backgroundWorker1.IsBusy)
            {
                restartWorker = true;
                backgroundWorker1.CancelAsync();
                return;
            }
            MessageBox.Show("Worker has cancelled");
            restartWorker = false;
            return;
        }
    }
开始按钮:

private void button1_Click(object sender, EventArgs e)
    {
        if (backgroundWorker1.IsBusy)
        {
            restartWorker = true;
            backgroundWorker1.CancelAsync();
        }
        else
        {
            backgroundWorker1.RunWorkerAsync();
        }
        button2.Enabled = true;
    }
取消按钮:

  private void button2_Click(object sender, EventArgs e)
    {
        backgroundWorker1.CancelAsync();
    }
现在,这一切都可以很好地取消一次,当我尝试在其他文件夹上重新开始时,我会出现以下错误:

mscorlib.dll中发生“System.IO.IOException”类型的异常,但未在用户代码中处理

其他信息:进程无法访问文件“C:\Users\Pierre\Desktop\Test Folder-Copy\New Text Document-Copy-Copy-Copy-Copy-Copy-Copy(8).txt.fdf”,因为其他进程正在使用该文件

这段代码包含了我所研究的所有内容,所以它应该能显示我在这方面的全部进展。我们非常感谢您为我们提供的指导


编辑:代码实际上适用于第二个文件夹,也就是说,它生成了文件,但还是抛出了异常。

您没有明确释放
StreamWriter
对象,因此只有在GC启动对象并释放文件时才会释放它。为避免此问题,请按如下方式更改您的
DoExcel
方法:

public static void DoExcel (string FolderPath)
{
    using (System.IO.StreamWriter file = new System.IO.StreamWriter(FolderPath + ".fdf"))
    {
        Thread.Sleep(1000);
        file.Close();
    }
}

DoExcel
方法对该文件不做任何处理,并使其保持打开状态。只有当GC拾取对象时,它才会处理文件资源。下面是:在释放对TextWriter的最后一次引用之前,始终调用dispose。否则,在垃圾收集器调用TextWriter对象的Finalize方法之前,它正在使用的资源将不会被释放。我又读了一遍,它是对的。看来你和我说了同样的话,我无法表达我是多么的感激,你可能因此保住了我的工作!我也不敢相信我竟然忽视了这一点!