Мой ответ на комментарии специалиста.
1. Синхронизации я так и не нашел, что, собственно, и удалось легко подтвердить, запустив многократно "Start
massive test in a separate thread", что привело к падению.
А параллельная работа с файловой системой — первое требование.
Параллельная работа с файловой системой реализована. Синхронизацию можно увидеть здесь:
/// <summary>
/// A facade for VirtualFS. Thread-safe.
/// </summary>
[Synchronization]
public class FsDisk : ContextBoundObject, IDisposable
{
...
}
и здесь:
/// <summary>
/// A synchronized FileStream
/// </summary>
[Synchronization]
internal class FsSyncFileStream : ContextBoundObject, IDisposable
{
...
}
Конкретно, она реализована с помощью контекста синхронизации. Все публичные методы класса FsDisk — атомарны. Все публичные методы класса FsFileStream — также атомарны. Поскольку экземпляры FsFileStream создаются внутри экземпляра FsDisk, они используют тот же контекст, т.е. пока выполняется любой метод FsDisk, другие потоки не могут войти в другие методы FsDisk и в методы FsFileStream.
Насколько я понял, "падение" возникало следующее:
При параллельной работе нескольких тестовых потоков периодически возникает ситуация, когда два потока пытаются обратиться к одному и тому же файлу. В соответствии с заданием, в этом случае FsDisk кидает исключение:
UnauthorizedAccessException("The file is open");
которое ловится в вызывающем методе. Эта ситуация нормальна, и тест специально реализован таким образом, чтобы демонстрировать правильность работы в этом случае. Но Visual Studio по умолчанию всегда останавливает выполнение программы при этом исключении, независимо от того, обработано оно или нет. Чтобы этого не происходило, нужно либо убрать соответствующую галочку в окне Debug->Exceptions, либо не запускать тест под отладчиком.
В новом варианте по кнопке запускается не один, а сразу 10 потоков.
2. Жаль, что асинхронную активность нельзя прервать.
Реализовано в новом варианте. Текущий прогресс отображается в "статус-баре", а прервать операцию можно кнопкой Cancel. Обращаю внимание, что в исходном задании эта функциональность не значилась.
3. FsFileTable::CreateFolder зачем-то написана рекурсивно, хотя рекурсия легко сворачивается в цикл.
Согласен. Виноват. Переделано.
4. Само архитектурное решение сомнительно, но это как раз повод для очного разговора.
Ни в коем случае не претендую на максимальную производительность, а скорее претендую на золотую середину между производительностью и временными затратами на разработку. Буду рад обсудить все это при очном разговоре.