我有一个用 c# (Visual Studio 2010) 开发的 Windows 应用程序,它与连接到 PC USB 端口的 USB-CAN 转换器交互。我在一个线程上实现了一个 UI,在一个单独的线程上实现了传输和接收逻辑。完成我的任务后,我想关闭这个线程并返回到当前挂起的 UI 线程!!
我试图使用 abort 函数强行终止线程,但它抛出异常。那么如何在完成我的任务后优雅地结束这个线程。
我有以下两个问题:
- 如何优雅地终止线程并返回到 UI 线程?
- 为什么这个发送和接收线程没有中止和挂起 UI 线程?
以下代码供您引用:
#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
最佳答案
How to gracefully terminate the thread and return to the UI thread?
如果线程在其中一个 UcanDotNet 调用中阻塞,那么您将不得不使用另一个 UcanDotNet API 来解除阻塞...假设该库能够正常终止其操作之一。我不熟悉这个 UcanDotNet 库,所以我不知道它的功能是什么。
如果像大多数第 3 个库一样,这个 UcanDotNet 库没有提供取消操作的必要方法,那么您真的别无选择,只能将所有这些调用放在另一个进程中并通过 WCF 与其通信。这样,如果您必须突然终止它,那么您只需终止进程。终止另一个进程比调用 Thread.Abort
更安全,因为中止线程会破坏内存。
Why is this transmission and reception thread not aborting and hanging the UI thread?
Thread.Abort
是一个阻塞调用。它等待中止被注入(inject)到线程中。我怀疑您的问题是线程在不允许异步异常注入(inject)的上下文中运行,例如 finally
block 或非托管代码。使用以下代码可以很容易地证明这一点。
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!
}
关于C#多线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10027652/