3

I'm debugging a test that periodically raises an IOException, noting that a file can not be deleted because it is being used by another process. I suspect that the process is indeed my test harness, and that some other thread in the process hasn't disposed of its file resources when I expected it to.

Is there a tool that I can use to determine which thread holds the impeding lock? If I can identify the thread, then I can inspect its call stack and at least try to determine why the resource is not yet disposed. The SOS debugging tool looks promising, but I don't see any feature that would remove a fair amount of guesswork from my investigation.

One thought is to identify the native OS thread-ID, which then can be mapped to a managed thread ID via SOS. How would I accomplish the former?

4

3 回答 3

5

您可以使用 SysInternals 工具中的 Process Explorer。http://technet.microsoft.com/en-us/sysinternals/bb896653 只需打开它并搜索您的文件名。它会告诉你哪些进程锁定了它。


编辑:

哦,我刚刚重新阅读并注意到您要求提供特定的线程。我不知道 ProcessExplorer 是否可以做到这一点。对不起!


编辑2:

第二个答案,扩展了 agent-j 的答案:

如果您可以编辑代码并在其周围添加一个 try/catch 以获取 IOException,您还可以记录堆栈跟踪,因为这听起来像是您想要检查的内容:

catch(IOException)
{
    LogMessage( string.Format(
        "Managed Thread Id: {0}",
        System.Threading.Thread.CurrentThread.ManagedThreadId) );

    LogMessage( string.Format(
        "Stack Trace: {0}",
        new System.Diagnostics.StackTrace(true).ToString()) );
}

编辑 3

使用上述方法,您还可以记录进程中所有线程的线程和堆栈跟踪,从而更容易查看日志并找出事后发生的情况。更新代码:

catch(IOException)
{
  foreach (var thread in System.Diagnostics.Process.GetCurrentProcess().Threads)
  {
    LogMessage(string.Format(
      "Managed Thread Id: {0}",
      thread.ManagedThreadId));

    LogMessage(string.Format(
      "Stack Trace: {0}",
      new System.Diagnostics.StackTrace(thread, true).ToString()));

  }
}
于 2011-06-14T19:42:40.360 回答
2

如果在try{delete();}catch(IOException)catch 子句中放置断点。难道你不能看看每个线程的调用堆栈吗?

于 2011-06-14T19:41:45.600 回答
0

线程不会锁定文件(至少对于操作系统而言不是)。考虑以下示例。该线程t创建一个文件并锁定该文件。主线程写入流并关闭它。这表明线程不拥有锁。过程确实如此。

     Stream stream = null;
     Thread t = new Thread(() => stream = File.OpenWrite (@"c:\temp\junk111.txt"));
     t.Start();
     Thread.Sleep(1000);
     Console.WriteLine(t.ThreadState);
     stream.WriteByte(89);
     stream.Close();
     File.OpenWrite (@"c:\temp\junk222.txt");

打印stopped,因此打开文件的线程不再运行,但它创建的文件句柄仍然打开。

这是上述文件的 FxCop 结果的相关部分

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop>FxCopCmd.exe /file:c:\code\jeremy.sellars\test\Junk\bin\Debug\Junk.exe /console
Microsoft (R) FxCop Command-Line Tool, Version 10.0 (10.0.30319.1) X86
Copyright (C) Microsoft Corporation, All Rights Reserved.

...
[Location not stored in Pdb] : warning  : CA2210 : Microsoft.Design : Sign 'Junk.exe' with a strong name key.
C:\code\jeremy.sellars\TEST\Junk\Program.cs(50,1) : warning  : CA2000 : Microsoft.Reliability : In method 'Program.Main()', call System.IDisposable.Dispose on object 'File.OpenWrite("c:\\temp\\junk2.txt")' before all references to it are out of scope.
Done:00:00:06.1251568

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop>
于 2011-06-15T16:11:18.860 回答