C#多线程问题
我有一个在c#(Visual Studio 2010)中开发的windows应用程序,它与连接到PC USB端口的USB-CAN转换器交互。我在一个线程上实现了UI,在另一个线程上实现了传输和接收逻辑。完成任务后,我想关闭此线程并返回当前挂起的UI线程 我试图使用abort函数强制终止线程,但它抛出了一个异常。那么,如何在完成任务后优雅地结束这个线程呢 我有以下两个问题:C#多线程问题,c#,winforms,multithreading,C#,Winforms,Multithreading,我有一个在c#(Visual Studio 2010)中开发的windows应用程序,它与连接到PC USB端口的USB-CAN转换器交互。我在一个线程上实现了UI,在另一个线程上实现了传输和接收逻辑。完成任务后,我想关闭此线程并返回当前挂起的UI线程 我试图使用abort函数强制终止线程,但它抛出了一个异常。那么,如何在完成任务后优雅地结束这个线程呢 我有以下两个问题: 如何优雅地终止线程并返回UI线程 为什么这个传输和接收线程没有中止和挂起UI线程 以下代码供您参考: #region rec
#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
如何优雅地终止线程并返回UI线程
如果线程在其中一个UcanDotNet调用中阻塞,则必须使用另一个UcanDotNet API来解除阻塞…假设此库能够正常终止其一个操作。我不熟悉这个UcanDotNet库,所以我不知道它的功能是什么
如果像大多数第三库一样,这个UcanDotNet库没有提供取消操作的必要手段,那么您真的没有其他选择,只能将所有这些调用放在另一个进程中,并通过WCF与之通信。这样,若您必须突然终止它,那个么您只需终止进程。终止另一个进程比调用线程更安全。无论如何,中止,因为中止线程会损坏内存
为什么这个传输和接收线程没有中止和挂起
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!
}
如何优雅地终止线程并返回UI线程
如果线程在其中一个UcanDotNet调用中阻塞,则必须使用另一个UcanDotNet API来解除阻塞…假设此库能够正常终止其一个操作。我不熟悉这个UcanDotNet库,所以我不知道它的功能是什么
如果像大多数第三库一样,这个UcanDotNet库没有提供取消操作的必要手段,那么您真的没有其他选择,只能将所有这些调用放在另一个进程中,并通过WCF与之通信。这样,若您必须突然终止它,那个么您只需终止进程。终止另一个进程比调用线程更安全。无论如何,中止,因为中止线程会损坏内存
为什么这个传输和接收线程没有中止和挂起
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!
}
我很困惑。您有GUI线程和其他线程执行USB/CAN通信。为什么GUI线程挂起?如果它挂起是因为您试图向comms线程发送终止信号并等待其句柄(thread.Join),那么就不要这样做!发信号让它结束,好吧,别再等了。不管怎样,你需要它来完成吗?为什么不把它放在一边呢?这可能是一个使用BackgroundWorker的好地方,在这种情况下index==2
你有一个注释//退出这个线程
,但你没有设置fDoExit=true
。我很困惑。您有GUI线程和其他线程执行USB/CAN通信。为什么GUI线程挂起?如果它挂起是因为您试图向comms线程发送终止信号并等待其句柄(thread.Join),那么就不要这样做!发信号让它结束,好吧,别再等了。你需要它来完成吗?为什么不把它放在一边呢?这可能是一个使用BackgroundWorker的好地方,在这种情况下index==2
你有一个注释//退出这个线程
,但你没有设置fDoExit=true
。