1

我正在开发一个应用程序,该应用程序必须根据放置在文件观察者监视的文件夹中的文件做出特定决定。

此决策过程的一部分涉及重命名文件,然后再将它们移至另一个文件夹进行处理。

由于我正在处理所有不同大小的文件,因此我创建了一个对象,该对象在单独的线程中检查文件以验证它是否“可用”以及何时触发事件。

当我从这个可用事件中运行重命名代码时,它可以工作。

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。
  • 在构建文件时验证:如果文件存在则为真,

    Thread toAvailableCheck = new Thread(new ThreadStart(AvailableCheck));
    toAvailableCheck.Start();
    
  • AvailableCheck 方法反复尝试打开文件的流读取器,直到创建读取器或尝试次数超时。如果阅读器被打开,它会触发 FileAvailable 事件,如果没有,它会触发 FileUnAvailable 事件,并在事件中传回自身。

  • 客户端应用程序被连接以从 FSW 的 Oncreated 事件中捕获这些事件。

  • OnFileAvailable 方法然后调用包含 excel 互操作调用的重命名功能。
  • 如果文件正在被重命名(未转换,扩展名保持不变),它会移动将名称从旧文件名更改为新文件名,如果是转换,它会运行一个转换工厂对象,该对象返回正确的转换类型基于源文件的扩展名和目标文件名。
  • 如果它是一个简单的重命名,它可以工作 w/oa 问题。如果它是一个转换(这是作为工厂的一部分返回的 XLS 到 CSV 对象),它所做的第一件事就是创建一个新的应用程序对象。这就是应用程序爆炸的地方。

当我在线程之外测试工厂和转换/重命名过程并在其自己的单元测试中,该过程可以正常工作而没有 oa 问题。

更新:

我通过执行以下操作在线程内测试了 Excel 互操作:

[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);

在线程实例化之后和线程开始调用之前,仍然得到同样的错误。我得到了我将不得不重新考虑设计的想法。

4

1 回答 1

2

有人在调用 Thread.Abort()。那可能是 CLR,由于未处理的异常而试图关闭您的程序。您可能会看到 ThreadAbortException 而不是真正的异常的原因是因为您在不是单线程单元的线程中使用了 COM 服务器(如 Excel)。检查 Thread.SetApartmentState() 的文档。像 FileSystemWatcher 用来引发事件的线程池线程不能是 STA。

还要检查调试器通知的输出窗口并使用 Debug + Exceptions, Throw 框使调试器在第一个异常时停止。

于 2010-12-20T21:02:37.127 回答