C#多线程问题

时间:2012-04-05 11:23:47

标签: c# winforms multithreading

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

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

我有以下两个问题:

  1. 如何优雅地终止线程并返回UI线程?
  2. 为什么这个传输和接收线程没有中止并挂起UI线程?
  3. 以下代码供您参考:

    #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
    

1 个答案:

答案 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!
}