2

我有一个用 c# (Visual Studio 2010) 开发的 Windows 应用程序,它与连接到 PC 的 USB 端口的 USB-CAN 转换器交互。我在一个线程上实现了 UI,在单独的线程上实现了传输和接收逻辑。完成我的任务后,我想关闭这个线程并返回到当前挂起的 UI 线程!!

我尝试使用 abort 函数强行终止线程,但它引发了异常。那么如何在我的任务完成后优雅地结束这个线程。

我有以下两个问题:

  1. 如何优雅地终止线程并返回UI线程?
  2. 为什么这个发送和接收线程没有中止和挂起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
4

1 回答 1

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!
}
于 2012-04-05T13:58:13.857 回答