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を実行しているクライアントアプリケーション
  • OnFileCreatedイベントファイルのパスを渡すFileObjectを作成します。
  • 構築時にファイルが検証されます。ファイルが存在する場合はtrueの場合、

    Thread toAvailableCheck = new Thread(new ThreadStart(AvailableCheck));
    toAvailableCheck.Start();
    
  • AvailableCheckメソッドは、リーダーが作成されるか、試行回数がタイムアウトするまで、ファイルに対してストリームリーダーを繰り返し開こうとします。リーダーが開かれている場合は、FileAvailableイベントが発生し、開かれていない場合は、FileUnAvailableイベントが発生し、イベントに戻ります。

  • クライアントアプリケーションは、FSWのOncreatedイベント内からこれらのイベントをキャッチするように配線されています。

  • 次に、OnFileAvailableメソッドは、Excelの相互運用機能呼び出しを含む名前変更機能を呼び出します。
  • ファイルの名前が変更されている場合(変換されていない場合、拡張子は同じままです)、名前を古いファイル名から新しいファイル名に変更するために移動し、変換されている場合は、正しいタイプの変換を返す変換ファクトリオブジェクトを実行しますソースファイルの拡張子と宛先ファイル名に基づきます。
  • 単純な名前変更の場合は、問題なく機能します。変換(ファクトリの一部として返されるXLSからCSVオブジェクト)の場合、最初に行うことは、新しいアプリケーションオブジェクトを作成することです。ここで、アプリケーションが爆撃されます。

スレッドの外部でファクトリと変換/名前変更プロセスをテストし、それ自体の単体テストでプロセスが問題なく機能する場合。

アップデート:

これを実行して、スレッド内で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にすることはできません。

また、[出力]ウィンドウでデバッガー通知を確認し、[デバッグ+例外、スロー]ボックスを使用して、最初の例外でデバッガーを停止します。

于 2010-12-20T21:02:37.127 に答える