我有一个C#WPF程序,它阻止了Windows API调用。当声卡/窗口进入错误状态时,该调用将永久阻止该线程。
我编写了代码,以便程序执行超时'并继续执行该程序。但是,Thread.Abort()
调用实际上并未成功中止该线程。一旦用户选择按下关闭,调用API的线程就会继续存在并阻止我的程序稍后关闭。
有没有办法强制关闭挂起的线程?如果没有,是否有更好的方法来关闭应用程序而不是在这种情况下调用Environment.Exit(1)
强制应用程序关闭?
代码的简短版本如下所示:
//Program starts
try
{
new OutputDevice();
}
catch
{
//Tell the user that midi won't work, but otherwise carry on as usual
}
//Output device class
public class OutputDevice():Device
{
//This method never returns a value when Windows or the hardware misbehave
[DllImport("winmm.dll")]
private static extern int midiOutOpen(ref int handle, int deviceID,MidiOutProc proc, int instance, int flags);
public OutputDevice(int deviceID) : base(deviceID)
{
//Set up some variables
var midiOutProc = HandleMessage;
//This function calls the windows API when called, and hangs waiting for a response
Func<int> openMidi = ()=>midiOutOpen(ref hndle, deviceID, midiOutProc, 0, CALLBACK_FUNCTION);
//Try to call openMidi, and if that times out or returns an error, then throw an exception
int result;
if (!TryExecute<int>(openMidi, 20000, out result))
{
result = Constants.TimeoutCode;
}
if(result != Constants.MMSYSERR_NOERROR)
{
throw new Exception(result);
}
}
///<summary>
///Tries to execute a function on another thread. If the operation times out, aborts the thread and returns false.
///</summary>
public static bool TryExecute<T>(Func<T> func, int timeout_milliseconds, out T result)
{
var t = default(T);
var thread = new System.Threading.Thread(() => t = func());
thread.Start();
var completed = thread.Join(timeout_milliseconds);
if (!completed)
{
//timeout
thread.Abort();
}
result = t;
return completed;
}
///<summary>
/// Handles Windows messages.
/// </summary>
protected virtual void HandleMessage(int handle, int msg, int instance, int param1, int param2)
{
//Handle the message
}
}
谢谢!