Is it possible to safely cancel a long running LogParser query from C#?
I'm working with LogParser 2.2 in C# via COM interop and would like to be able to give long running queries a timeout.
e.g.
var ctx = new COMIISW3CInputContextClassClass();
var log = new LogQueryClassClass();
var rs = log.Execute(qry, ctx);
Is it possible to i开发者_如何转开发nterrupt the log.Execute
call if it takes too long?
I have tried Thread.Abort()
, but it appears the ThreadAbortException waits until the Execute call finishes normally.
The code used to test Thread.Abort()
is:
var ctx = new COMIISW3CInputContextClassClass();
var log = new LogQueryClassClass();
ILogRecordset rs = null;
var t = new Thread(() =>
{
rs = log.Execute(qry, ctx);
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join(100);
t.Abort();
// this tests if the file lock is still held by log parser
Assert.Throws<IOException>(() =>
File.OpenWrite(path));
t.join(10000);
// file is no longer locked
using (File.OpenWrite(path))
Assert.IsTrue(true);
Cancelling execution with Thread.Abort
is rarely safe. It is not safe in this case as there is no way to know the state of Log Parser's data structures. You could perform the query in a separate process which you communicate with using standard input/output, named pipes, WCF, or your favorite IPC technology. Then to cancel the query, use Process.Kill
on that process.
NOTE: Don't know if Log Parser writes any temp files that this will leave behind. Other than that, Windows should clean up all state correctly for you.
See cancellation tokens: http://msdn.microsoft.com/en-us/library/dd997289.aspx
精彩评论