我有一个用c#开发的Windows应用程序(Visual Studio 2010),它与连接到PC的USB端口的USB-CAN转换器进行交互。我在一个线程上实现了一个UI,并在一个单独的线程上实现了传输和接收逻辑。完成我的任务后,我想关闭这个线程并返回到当前挂起的UI线程!!
我尝试使用abort函数强制终止该线程,但它抛出异常。那么如何在完成任务后优雅地结束这个线程。
我有以下两个问题:
以下代码供您参考:
#region recievedthrad
public void ThreadProcReceive()
{
try
{
bool fDoExit = false;
do
{
if (bFlag)
DeleteAllResources(); // This will free all the driver resources.
// wait for receiving messages or exiting this thread
/* Note: After completion of the task, this method needs to return a 0 or 2 value. But still it returns 1 or 258 and never exits the thread. */
int index = WaitHandle.WaitAny(m_RxWaitHandles);
if (index == 0)
{
// exit this thread
fDoExit = true;
}
else if (index == 1)
{
// receive all messages
ReceiveAllCanMessages();
}
else if (index == 2)
{
// exit this thread
ReceiveStatus(UcanDotNET.USBcanServer.USBCAN_CHANNEL_CH0);
}
} while ((fDoExit == false));
}
catch(Exception ex)
{
}
}
#endregion
答案 0 :(得分:0)
如何优雅地终止线程并返回UI线程?
如果线程在其中一个UcanDotNet调用中阻塞,那么您将不得不使用另一个UcanDotNet API来解除阻塞...假设此库能够正常终止其中一个操作。我不熟悉这个UcanDotNet库,所以我不知道它的功能是什么。
如果像大多数第三个库一样,这个UcanDotNet库没有提供取消操作的必要方法,那么除了将所有这些调用放在另一个进程中并通过WCF与它通信之外别无选择。这样,如果你必须突然终止它,那么你只需要杀死进程。杀掉另一个进程比调用Thread.Abort
更安全,因为中止线程会破坏内存。
为什么这个传输和接收线程不会中止和挂起 UI线程?
Thread.Abort
是一个阻止通话。它等待中止注入线程。我怀疑你的问题是线程是在不允许异步异常注入的上下文中运行的,例如finally
块或非托管代码。使用以下代码可以很容易地证明这一点。
public static void Main(string[] args)
{
int i = 0;
var t = new Thread(() =>
{
try
{
}
finally
{
while (true) i++;
}
});
t.Start();
Thread.Sleep(1000);
t.Abort(); // this blocks indefinitely!
Console.WriteLine("aborted"); // never gets here!
}