C# 如何在c中删除另一个线程或进程中使用的文件#

C# 如何在c中删除另一个线程或进程中使用的文件#,c#,multithreading,backgroundworker,delete-file,ioexception,C#,Multithreading,Backgroundworker,Delete File,Ioexception,在这里,我有一个包含2个文件夹和文件夹中的一些xml文件的某种格式的文件 然后读取每个文件,并根据保存的文件文本呈现一些UI元素。打开时,我将显示等待指示框以及加载的进程正在后台与dispatcher一起执行 如果我想中止该操作,请单击中止,不需要执行任何操作(呈现UI元素)。在这里,我将删除临时位置,它将显示“进程无法访问此文件,因为它被另一进程使用”异常。我可以知道如何删除该文件或该文件使用的进程吗 这是我的密码: 我使用CancellationToken对中止所有方法进行了编辑 var b

在这里,我有一个包含2个文件夹和文件夹中的一些xml文件的某种格式的文件

然后读取每个文件,并根据保存的文件文本呈现一些UI元素。打开时,我将显示等待指示框以及加载的进程正在后台与dispatcher一起执行

如果我想中止该操作,请单击中止,不需要执行任何操作(呈现UI元素)。在这里,我将删除临时位置,它将显示“进程无法访问此文件,因为它被另一进程使用”异常。我可以知道如何删除该文件或该文件使用的进程吗

这是我的密码:

我使用CancellationToken对中止所有方法进行了编辑

var backGroundWorker = new CancelSupportedBackgroundWorker { WorkerSupportsCancellation = true };
CancellationTokenSource source = new CancellationTokenSource(); 
AlertBox = new AlertBox { IsBusy = true };
AlertBox.WaitingText = Loading;
AlertBox.WaitingHeaderText = Loading Indicator;
AlertBox.AbortButton.Click += (obj, arg) =>
{
    App.Current.Dispatcher.Invoke(new Action(() =>
    {
        string tempDir = C:\Users\Lenovo\AppData + FileAndDirectoryConstants.TempDirFolder;
        if (Directory.Exists(tempDir))
        {
            Directory.Delete(tempDir, true);
        }
      }));

GC.Collect();
source.Cancel();
GC.WaitForPendingFinalizers();
backGroundWorker.CancelAsync();
backGroundWorker.Abort();
backGroundWorker.Dispose();
}

backGroundWorker.DoWork += (obj, arg) =>
{
    try
    {
        RenderUiElements(fileName,(CancellationToken)arg.Argument);
    }
    catch (ThreadAbortException)
    {
        Dispatcher.Invoke(() =>
        {
            AlertBox.IsBusy = false;
        }, System.Windows.Threading.DispatcherPriority.Background);
        arg.Cancel = true;
    }
};
backGroundWorker.RunWorkerCompleted += (obj, arg) =>
{
    AlertBox.isBusy = false;
}
backGroundWorker.RunWorkerAsync(source.Token);

private void RenderUiElements(string fileName,CancellationToken token)
{
    try
    {
        if(token != default(CancellationToken))
           if(token.isCancellationRequested)
              return;
        App.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(
        delegate ()
        {
            using (fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None))
            {                                
                LoadReport(fileStream, fileName,token);
            }
        }));
    }
    catch (ThreadAbortException)
    {
        return;
    }
    finally
    {
        if (fileStream != null)
        {
            fileStream.Close();
            fileStream.Dispose();
        }
    }
}

只有两种方法可以删除另一进程正在使用的文件

  • 强制关闭文件上当前打开的所有文件句柄,然后删除该文件
  • P/调用Windows MoveFileEx函数,并使用目标名称为空的MOVEFILE_DELAY_UNTIL_REBOOT标志。这将在您重新启动时删除该文件

我建议您执行后一种操作,因为执行前一种操作非常糟糕,可能会给其他正在运行的应用程序带来严重问题。关于后者的更多信息,请参见

最后,我找到了解决方案

在这里,Filestream对象没有被正确地释放,它只有在LoadReport方法完全释放之后才被释放。如果在执行LoadReport时单击abort,则不会释放文件流。因此发生了错误

因此,清除LoadReport()方法中的Filestream对象


我认为,
LoadReport
在您中止操作时仍在使用
fileStream
,这就是您收到消息的原因是,这就是原因。因为Loadreport正在使用该文件流执行某些操作。此时,我们需要中止该操作并尝试删除该文件夹。以下是几种方法:该方法用于检查文件是否已锁定。但是我需要删除该文件。为什么不取消
LoadReport
中的操作呢?在此之后,您应该能够删除文件如何关闭当前在文件上打开的所有文件句柄我故意没有给出一个例子,因为这是一件可怕的事情。如果你想这样做,你需要做一点谷歌搜索。确保您确实想要这样做,并且它不是您自己的代码仍然具有特定文件的打开句柄。请考虑采用后一种方法。
private void LoadReport(stream filestream,CancellationToken token)
{
 filestream.Close();
 filestream.Dispose();
}