2009-12-24 90 views
3

我发现自己处于令人讨厌的情况,即在调试会话完成后,visual studio调试器不能自行释放。因此,devenv.exe的保留对可执行文件的锁,我不能重建项目,由于可怕的错误:以后每运行周期是不强制Visual Studio 2008调试器发布可执行文件

Error 1 Unable to copy file "obj\Debug\program.exe" to "bin\Debug\program.exe". The process cannot access the file 'bin\Debug\program.exe' because it is being used by another process.

这可以通过重新启动Visual Studio中,但重新启动我的整个IDE固定恰好有利于良好的编码环境。建立 - >清洁没有帮助。

我google了这个错误,虽然症状似乎是相当普遍的基本原因是不同的。主要我想知道,按重要性排序:

  1. 是否有任何快速的方法来解锁文件,而无需重新启动Visual Studio?
  2. 除此之外,我应该采用什么防御性编程技术来防止这种情况?
  3. 在下面的例子中幕后究竟发生了什么,导致调试器不能释放?

一个会产生这种症状的代码的例子就在这里。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var f1 = new Form1(); 
     f1.Dir = "asdf"; 
    } 
} 

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private FileSystemWatcher fsw; 

    public string Dir 
    { 
     get { return fsw.Path;} 
     set 
     { 
      fsw = new FileSystemWatcher(value); 
      fsw.EnableRaisingEvents = true; 
      throw new Exception("asdf"); 
     } 
    } 

    ~Form1() 
    { 
     if (fsw != null) 
      fsw.Dispose(); 
    } 
} 

重现:

  1. 运行Program.Main使用Visual Studio 2008中的调试器。
  2. 当抛出异常时停止调试。
  3. 更改源代码并尝试重建。

编辑:各种各样的解决方案:

public Form1() 
{ 
    InitializeComponent(); 
    this.Closing += (sender, args) => 
    { 
     if (watcher != null) 
      watcher.Dispose(); 
    }; 
} 

我仍然有兴趣在为什么这个工作,并同时将其放置在析构函数没有。

+0

您使用的是Windows 7吗? – 2009-12-24 16:11:43

+0

没有。带有VS 9.0.30729.1 SP的Windows XP SP3。这是为.NET 3.5 SP1构建的项目 – fostandy 2009-12-24 16:23:53

回答

1

攻击这个问题的方法之一,你应该在你的工具带中作为开发人员的方法是使用MS/Sys Internals中的Process Explorer。它的一个功能允许您搜索系统中打开的手柄,并在发现时杀死手柄。这是一个非常方便和免费的应用程序。现在,这并不能解决你的核心问题,但它会有帮助。

+0

谢谢。是的,这是什么证实它是devenv.exe是锁定它。 – fostandy 2009-12-24 16:24:26

+0

你是否试过在文件上杀死Dev Env的文件句柄来释放它? – 2009-12-24 16:26:57

+0

啊不,我没有。我刚刚走了。虽然句柄不再显示在进程资源管理器搜索中,我也不能在devenv.exe进程下看到它,但我仍然无法生成项目或手动删除文件。 – fostandy 2009-12-24 16:34:01

0

我以前也有这个问题。

运行使用.bat:

taskkill /F /IM program.exe 
taskkill /F /IM program.vshost.exe 

通常解决我的问题......

0

你不是一个终结处置?终结器由机器管理,而开发人员负责处理。 Finalzers是非确定性的,而处置是确定性的。

也许你可以尝试在表单的“Disposed”事件中处理。

0

不要使用析构函数~。不要在析构函数中调用Dipose()