Ответ 1
Признавая, что вам нужен быстрый способ проверить, тратить ли больше времени на отладку кода или, может быть, написать хорошие тесты, чтобы доказать, что ваш код в порядке, то, что вы хотите, - это быстрый способ доказать, что никакой другой процесс не является используя ваш файл. Итак, давайте предположим:
- Ваш файл находится на локальном диске (а не на сетевом ресурсе) и
- вы подозреваете, что антивирус, индексирование Windows или что-то еще блокирует файл, отличный от вашего кода.
- поэтому вам нужно быстро определить, что в/из перед написанием тестов
Вы хотите иметь возможность запускать свою программу и посмотреть, что произошло с этим файлом, до того, как вы нарушили нарушение.
Я бы сделал это:
1. Загрузить ProcMon из sysinternals (10 секунд)
Procmon - отличный инструмент, вы можете отфильтровать до того, что хотите видеть во всех процессах в последовательном порядке. Ссылка на procmon в sysinternals, от Microsoft
2. Извлеките и запустите Procmon, добавьте фильтры и блики (30 секунд)
Откройте procmon, добавьте фильтр для "Путь" "начинается с" ""
Теперь добавьте выделение для "Result" "is" "SHARING VIOLATION"
И, наконец, запустите свою программу, пока не получите исключение, затем щелкните правой кнопкой мыши файл с нарушением совместного доступа в столбце пути и выберите "Включить" < имя файла здесь > ", чтобы удалить все другие результаты. Теперь вы можете увидеть всю активность для файла, вызвавшего ваше исключение...
Если вы хотите получить удовольствие от procmon, вот код, который я использовал, чтобы подделать это для вас. Он имеет боковой поток, который блокирует файл и основной поток, который затем пытается заблокировать файл. Просто создайте приложение консоли С# и отпустите. Это выглядит так:
Итак, менее чем за 2 минуты вы можете увидеть, не поврежден ли ваш код или что-то еще. Я использовал это на днях, чтобы определить, что мой компонент Com на самом деле использует альтернативные потоки файлов, и поэтому бросил исключение, когда он пытался использовать сетевой диск. Никакое количество модульных испытаний не помогло бы мне там.
И вот тестовый код, чтобы заставить нарушение обмена:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
internal class Program
{
private static int lockPoint = 0;
private static void Main(string[] args)
{
const string testFile = @"H:\test\test.txt";
FileInfo testFileInfo = new FileInfo(testFile);
if (!testFileInfo.Directory.Exists)
{
testFileInfo.Directory.Create();
}
// Clear our example
if (testFileInfo.Exists)
{
testFileInfo.Delete();
}
// Create the test file
using (FileStream fs = File.Create(testFile))
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine("test file content");
}
Task iLockTheFileFirst = new Task(() => {
using (FileStream fsThread = File.Open(testFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
Console.WriteLine("iLockTheFileFirst: I opened the file");
// Set lockPoint to 1 and let main try and open the file
Interlocked.Exchange(ref lockPoint, 1);
// Wait until the main thread sets lockPoint to 3
const int ifEqualTo3 = 3;
const int replaceWith4 = 4;
while (Interlocked.CompareExchange(ref lockPoint, replaceWith4, ifEqualTo3) != ifEqualTo3)
{
Console.WriteLine("iLockTheFileFirst: Waiting for main thread to let me finish");
Thread.Sleep(1000);
}
}
Console.WriteLine("iLockTheFileFirst: I have closed the file");
});
// Start the thread and lock the file
iLockTheFileFirst.Start();
// Now spin until the lockPoint becomes 1
const int ifEqualTo1 = 1;
const int replaceWith2 = 2;
// If lockPoint is equal to 1 (i.e. the main thread wants us to finish), then move it to 2
while (Interlocked.CompareExchange(ref lockPoint, replaceWith2, ifEqualTo1) != ifEqualTo1)
{
Console.WriteLine("Main thread: waiting for iLockTheFileFirst to open the file");
Thread.Sleep(1000);
}
try
{
Console.WriteLine("Main thread: now I'll try opening the file");
using (FileStream fsMain = File.Open(testFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
Console.WriteLine("Main thread: I opened the file, which shouldn't be possible");
}
}
catch (IOException ioex)
{
Console.WriteLine("Main thread: IOException: " + ioex.Message);
}
catch (Exception ex)
{
Console.WriteLine("Main thread: some other exception: " + ex.Message);
}
// Set lockPoint to 3 and let other thread finish
Interlocked.Exchange(ref lockPoint, 3);
// Wait for other thread to finish
const int ifEqualTo4 = 4;
const int replaceWith5 = 5;
while (Interlocked.CompareExchange(ref lockPoint, replaceWith5, ifEqualTo4) != ifEqualTo4)
{
Thread.Sleep(10);
}
Console.WriteLine("Main thread: Press enter to finish");
Console.ReadLine();
}
}
Что все люди!