【问题标题】:How can I restart a backgroundworker in a Windows Forms Application?如何在 Windows 窗体应用程序中重新启动后台工作程序?
【发布时间】:2014-01-19 00:40:01
【问题描述】:

我的代码基本上做的是它允许用户浏览包含一堆文件的文件夹,并且当用户单击“开始”按钮时,该代码会生成具有相同名称和不同扩展名的文件文件夹中的那些运行。我想要做的是添加一个取消按钮,因此如果用户单击不正确文件夹上的开始按钮,例如,用户可以取消,浏览到正确的文件夹,然后重新启动操作。 这是点击开始按钮时触发的代码:

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);
        }
    }

我的 RunWorkerComplete 方法如下所示:

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 (8).txt.fdf',因为它正在被另一个进程使用。

代码包含我研究过的所有内容,因此它应该几乎可以显示我在这方面的全部进展。非常感谢任何关于应该做什么的指导。

编辑:代码实际上适用于第二个文件夹,即它生成文件但无论如何都会引发异常。

【问题讨论】:

    标签: c# .net backgroundworker


    【解决方案1】:

    您没有显式释放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 拾取到对象时,它才会释放文件资源。
    • 这里来自documentation:在释放对 TextWriter 的最后引用之前,请始终调用 Dispose。否则,它正在使用的资源将不会被释放直到垃圾收集器调用 TextWriter 对象的 Finalize 方法。
    • 对不起,我错过了你回答的意思。我又读了一遍,它是对的。看来你和我说的一样
    • 我无法表达我的感激之情,您可能已经挽救了我的工作!我也不敢相信我怎么忽略了这一点!
    猜你喜欢
    • 2011-07-01
    • 2018-08-23
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多