2017-08-08 195 views
0

在这里,我有一个格式的文件,其中包含2个文件夹和一些XML文件在该文件夹中。当打开该文件时,我提取该文件在临时位置像应用程序数据。如何删除在另一个线程或进程在c#中使用的文件

然后读取每个文件,并基于保存的文件文本呈现一些UI元素。打开时,我将显示等待指示框以及加载过程在调度程序中执行的背景。

如果我想中止该操作,请单击中止并且不需要执行任何操作(呈现UI元素)。在此我将删除该临时位置,它将显示“该进程无法访问此文件,因为它被另一个进程使用“exception.May我知道如何删除该文件或哪个进程使用该文件?

这里是我的代码:

我做了修改,使用的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(); 
     } 
    } 
} 
+0

我想,'LoadReport'依然采用'fileStream'当你中止操作,这就是为什么你所得到的消息 – Ben

+0

是的,就是这个道理的原因。因为Loadreport使用该文件流进行一些操作。那时我们需要中止该操作并尝试删除该文件夹。 – Pandi

+0

以下是一些方法:[是否有方法检查文件是否正在使用?](https://stackoverflow.com/questions/876473/is-there-a-way-to-check-if-a -file-is-in-use/11060322#11060322) –

回答

1

只有2种方式,你可以通过另一个进程

  • 力的所有文件句柄当前打开到关闭文件删除使用中的文件,然后删除该文件
  • P /调用Windows MoveFileEx函数,并使用带有NULL目标名称的MOVEFILE_DELAY_UNTIL_REBOOT标志。这将在您重启时删除文件。

我建议你执行后者,因为前者是令人讨厌的,并可能对其他正在运行的应用程序造成严重问题。有关后者的详细信息,请参阅http://www.pinvoke.net/default.aspx/kernel32.movefileex

+0

如何关闭当前在文件上打开的所有文件句柄** – Pandi

+2

我故意没有给出一个例子,因为这是一件可怕的事情。如果你想这样做,你需要做一些Google搜索。确保你真的想要这样做,它不是你自己的代码仍然有一个特定的文件打开句柄。请考虑采取后一种方法 –

0

最后,我发现,溶液,

这里FileStream对象是不正确地设置其仅后LoadReport方法完全设置。如果我在做LoadReport时单击中止文件流不处理。所以发生错误。

所以清除LoadReport()方法中的Filestream对象。

private void LoadReport(stream filestream,CancellationToken token) 
{ 
filestream.Close(); 
filestream.Dispose(); 
} 
相关问题