Какой инструмент отладки (если есть) позволяет мне определить поток, который удерживает блокировку файла? - PullRequest
3 голосов
/ 14 июня 2011

Я отлаживаю тест, который периодически вызывает IOException, отмечая, что файл не может быть удален, поскольку он используется другим процессом. Я подозреваю, что этот процесс действительно является моим средством тестирования, и что какой-то другой поток в процессе не утилизировал свои файловые ресурсы, когда я ожидал этого.

Есть ли инструмент, который я могу использовать, чтобы определить, какой поток удерживает блокирующую блокировку? Если я могу определить поток, то я могу проверить его стек вызовов и, по крайней мере, попытаться определить, почему ресурс еще не удален. SOS-средство отладки выглядит многообещающе, но я не вижу ни одной функции, которая бы убрала из моих исследований немало догадок.

Одна мысль состоит в том, чтобы идентифицировать собственный идентификатор потока ОС, который затем можно сопоставить с идентификатором управляемого потока через SOS. Как бы я выполнил первое?

Ответы [ 3 ]

5 голосов
/ 14 июня 2011

Вы можете использовать Process Explorer из инструментов SysInternals. http://technet.microsoft.com/en-us/sysinternals/bb896653 Просто откройте его и найдите имя вашего файла. он покажет, какие процессы заблокированы.


Edit:

О, я просто перечитал это и заметил, что вы спросили о конкретной теме. Я не знаю, может ли ProcessExplorer сделать это. Извините!


Редактировать 2:

Второй ответ, который расширяет ответ агента-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()));

  }
}
2 голосов
/ 14 июня 2011

Если вы поставите точку останова в предложении try{delete();}catch(IOException) catch. Разве вы не можете посмотреть на стек вызовов каждого потока?

0 голосов
/ 15 июня 2011

Потоки не удерживают блокировки на файлах (по крайней мере, в том, что касается операционной системы). Рассмотрим следующий пример. Поток 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>
...