2

PC の USB ポートに接続された USB-CAN コンバーターと対話する c# (Visual Studio 2010) で開発された Windows アプリケーションがあります。1 つのスレッドに UI を実装し、別のスレッドに送受信ロジックを実装しました。タスクが完了したら、このスレッドを閉じて、現在ハングしている UI スレッドに戻りたいと思います!!

アボート機能を使ってスレッドを強制終了させようとしたところ、例外がスローされました。では、タスクの完了後にこのスレッドを正常に終了する方法。

次の 2 つの質問があります。

  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 を使用してブロックを解除する必要があります...このライブラリに操作の 1 つを正常に終了させる機能があると仮定します。私はこの UcanDotNet ライブラリに詳しくないので、その機能が何であるかわかりません。

ほとんどの 3rd ライブラリと同様に、この 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 に答える