Windows App. Thread Aborting Issue
I'm working on an application that has to make specific decisions based on files that are placed into a folder being watched by a file watcher.
Part of this decision making process involves renaming files before moving them off to another folder to be processed.
Since I'm working with files of all different sizes I created an object that checks the file in a seperate thread to verify that it is "available" and when it is it fires an event.
When I run the rename code from inside this available event it works.
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");
}
The problem I'm running into is that when the extensions are different from the source file and the rename to file I am making a call to a conversion factory that returns a factory object based on the type of conversion and then converts the file accordingly before doing the rename. When I run开发者_如何学JAVA that particular piece of code in unit test it works, the factory object is returned, and the conversion happens correctly.
But when I run it within the process I get up to the...
moExcelApp = new Application();
part of converting an .xls or .xlsx to a .csv and i get a "Thread was being Aborted" error.
Any thoughts?
Update:
There is a bit more information and a bit of map of how the application works currently.
- Client Application running FSW
- On File Created event Creates a FileObject passing in the path of the file.
On construction the file is validated: if file exists is true then,
Thread toAvailableCheck = new Thread(new ThreadStart(AvailableCheck)); toAvailableCheck.Start();
The AvailableCheck Method repeatedly tries to open a streamreader to the file until the reader is either created or the number of attempts times out. If the reader is opened, it fires the FileAvailable event, if not it fires the FileUnAvailable event, passing back itself in the event.
The client application is wired to catch those events from inside the Oncreated event of the FSW.
- the OnFileAvailable method then calls the rename functionality which contains the excel interop call.
- If the file is being renamed (not converted, extensions stay the same) it does a move to change the name from the old file name to the new, and if its a conversion it runs a conversion factory object which returns the correct type of conversion based on the extensions of the source file and the destination file name.
- If it is a simple rename it works w/o a problem. If its a conversion (which is the XLS to CSV object that is returned as a part of the factory) the very first thing it does is create a new application object. That is where the application bombs.
When i test the factory and conversion/rename process outside of the thread and in its own unit test the process works w/o a problem.
Update:
I tested the Excel Interop inside a thread by doing this:
[TestMethod()]
public void ExcelInteropTest()
{
Thread toExcelInteropThreadTest = new Thread(new ThreadStart(Instantiate_App));
toExcelInteropThreadTest.Start();
}
private void Instantiate_App()
{
Application moExcelApp = new Application();
moExcelApp.Quit();
}
And on the line where the application is instatntiated I got the 'A first chance exception of type 'System.Threading.ThreadAbortException' error.
So I added;
toExcelInteropThreadTest.SetApartmentState(ApartmentState.MTA);
after the thread instantiation and before the thread start call and still got the same error. I'm getting the notion that I'm going to have to reconsider the design.
Somebody is calling Thread.Abort(). That could be the CLR, trying to shut your program down because of an unhandled exception. The reason you might see the ThreadAbortException instead of the real exception is because you are using a COM server (like Excel) in a thread that isn't a single threaded apartment. Check the docs for Thread.SetApartmentState(). Threadpool threads like the ones that FileSystemWatcher uses to raise events cannot be STA.
Also check the Output window for debugger notifications and use Debug + Exceptions, Thrown box to make the debugger stop on the first exception.
精彩评论