我有一个 C# WPF 程序,它会阻塞 Windows API 调用。当声卡/Windows 进入错误状态时,调用会永久阻塞线程。
我编写了代码,以便程序执行“超时”并继续执行。但是,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
}
}
谢谢!