Приложение для Windows. Проблема прерывания потока

Я работаю над приложением, которое должно принимать конкретные решения на основе файлов, которые помещаются в папку, за которой наблюдает средство просмотра файлов.

Часть этого процесса принятия решений включает переименование файлов перед перемещением их в другую папку для обработки.

Так как я работаю с файлами разных размеров, я создал объект, который проверяет файл в отдельном потоке, чтобы убедиться, что он "доступен" и когда он запускает событие.

Когда я запускаю код переименования из этого доступного события, оно работает.

public void RenameFile_Test()
{
    string psFilePath = @"C:\File1.xlsx";
    tgt_File target = new FileObject(psFilePath);
    target.FileAvailable += new FileEventHandler(OnFileAvailable);
    target.FileUnAvailable += new FileEventHandler(OnFileUnavailable);
}

private void OnFileAvailable(object source, FileEventArgs e)
{
    ((FileObject)source).RenameFile(@"C:\File2.xlsx");
}

Проблема, с которой я сталкиваюсь, заключается в том, что когда расширения отличаются от исходного файла и переименования в файл, я выполняю вызов фабрики преобразования, которая возвращает объект фабрики на основе типа преобразования, а затем соответствующим образом преобразует файл перед делает переименование. Когда я запускаю этот конкретный кусок кода в модульном тесте, он работает, возвращается фабричный объект, и преобразование происходит правильно.

Но когда я запускаю его в процессе, я встаю на...

        moExcelApp = new Application();

часть преобразования.xls или.xlsx в.csv, и я получаю ошибку "Поток был прерван".

Какие-нибудь мысли?

Обновить:

Есть немного больше информации и немного карты того, как приложение работает в настоящее время.

  • Клиентское приложение под управлением FSW
  • Событие On File Created Создает FileObject, передавая путь к файлу.
  • При построении файл проверяется: если файл существует, то true,

    Thread toAvailableCheck = new Thread(new ThreadStart(AvailableCheck));
    toAvailableCheck.Start();
    
  • Метод AvailableCheck неоднократно пытается открыть потоковый ридер для файла, пока не будет создан ридер или не истечет количество попыток. Если читатель открыт, он запускает событие FileAvailable, если нет, то запускает событие FileUnAvailable, возвращая себя в этом событии.

  • Клиентское приложение подключено для перехвата этих событий из события Oncreated в FSW.

  • Затем метод OnFileAvailable вызывает функцию переименования, которая содержит вызов взаимодействия Excel.
  • Если файл переименовывается (не конвертируется, расширения остаются прежними), он перемещает, чтобы изменить имя со старого имени файла на новое, и, если это преобразование, он запускает объект фабрики конверсии, который возвращает правильный тип преобразования. на основе расширений исходного файла и имени файла назначения.
  • Если это простое переименование, это работает без проблем. Если это преобразование (то есть объект XLS в CSV, возвращаемый как часть фабрики), то самое первое, что он делает, - это создает новый объект приложения. Вот где приложение бомбы.

Когда я тестирую фабрику и процесс преобразования / переименования вне потока и в своем модульном тесте, процесс работает без проблем.

Обновить:

Я проверил Excel Interop внутри потока, выполнив это:

[TestMethod()]
public void ExcelInteropTest()
{
    Thread toExcelInteropThreadTest = new Thread(new ThreadStart(Instantiate_App));
    toExcelInteropThreadTest.Start();
}

private void Instantiate_App()
{
    Application moExcelApp = new Application();
    moExcelApp.Quit();
}

И в строке, где создается приложение, я получил ошибку "Исключение первого шанса типа" System.Threading.ThreadAbortException.

Итак, я добавил;

toExcelInteropThreadTest.SetApartmentState(ApartmentState.MTA);

после создания потока и перед началом вызова потока, и все еще получил ту же ошибку. Я понимаю, что мне придется пересмотреть дизайн.

1 ответ

Решение

Кто-то вызывает Thread.Abort(). Это может быть CLR, пытающийся закрыть вашу программу из-за необработанного исключения. Причина, по которой вы можете увидеть исключение ThreadAbortException вместо реального исключения, заключается в том, что вы используете COM-сервер (например, Excel) в потоке, который не является однопоточным. Проверьте документы для Thread.SetApartmentState(). Потоки потоков, подобные тем, которые FileSystemWatcher использует для создания событий, не могут быть STA.

Также проверьте окно "Вывод" на наличие уведомлений отладчика и используйте поле "Отладка + Исключения", "Брошенный", чтобы отладчик остановился при первом исключении.

Другие вопросы по тегам