我正在调试一个定期引发IOException
的测试,注意到一个文件不能被删除,因为它正被另一个进程使用。我怀疑这个进程确实是我的测试工具,并且进程中的其他线程没有像我期望的那样处理它的文件资源。
有没有工具可以用来确定哪个线程持有阻碍锁?如果我可以识别线程,那么我就可以检查它的调用堆栈,并至少尝试确定资源尚未释放的原因。SOS debugging tool看起来很有希望,但我没有看到任何可以从我的调查中消除大量猜测的功能。
一种想法是标识本机操作系统线程ID,然后可以通过SOS将其映射到托管线程ID。我该如何完成前者呢?
发布于 2011-06-14 19:42:40
您可以从SysInternals tools中使用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-14 19:41:46
如果您在try{delete();}catch(IOException)
catch子句中放置断点。你不能看看每个线程的callstack吗?
发布于 2011-06-15 16:11:19
线程不会锁定文件(至少对于操作系统而言不是这样)。考虑下面的例子。线程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>
https://stackoverflow.com/questions/6349032
复制相似问题