这可能是一个愚蠢的问题,如果这已经回答了其他地方,那么我真的很感激,如果我的搜索没有止跌回升有人可以点我给它任何明确的。的Thread.join在UI线程阻塞也子线程
概括地说,我的问题是,当我在已标记停止childThread一个子线程UI线程做childThread.Join()似乎要禁止以及主线程所以一切只是挂起。
由于使用Join会阻塞UI,因为childThread在被告知退出之后应该在一秒钟内完成,因此此刻本身并不是问题。
发生这种情况时,我正在等待运行重复进程的线程退出,然后才能运行另一种返回某些信息但不能与其他进程同时运行的方法。
我的Winforms申请通过pinvoking为硬件中的C API用一块USB硬件的集成。
硬件API具有将开始,将无限期地重复运行,并迅速与新的信息,然后我需要传递到UI回调的过程的方法。
此操作可以通过对硬件API的另一个调用取消,该硬件API设置硬件可以看到的标志,以便它知道要退出。
我包裹着我自己的C#代码这个C API和包装中的我不得不分拆启动过程调用在另一个线程,这样的活动不会阻止用户界面。
这里有大约我在做什么编辑的亮点。
public class DeviceWrapper
{
Thread childThread = null;
void DeviceWrapper
{
//Set the callback to be used by the StartGettingInformation() process
PInvokeMethods.SetGetInformationCallback(InformationAcquiredCallback);
}
public void StartProcess()
{
childThread = new Thread(new ThreadStart(GetInformationProcess))
childThread.Start();
}
void GetInformationProcess()
{
PInvokeMethods.StartGettingInformation();
}
//This callback occurs inside the childThread
void InformationAcquiredCallback(Status status, IntPtr information)
{
//This callback is triggered when anything happens in the
//StartGettingInformation() method, such as when the information
//is ready to be retrieved, or when the process has been cancelled.
if(status == Status.InformationAcquired)
{
FireUpdateUIEvent();
}
//If the cancel flag has been set to true this will be hit.
else if(status == Status.Cancelled)
{
//Reset the cancel flag so the next operation works ok
PInvokeMethods.SetCancelFlag(false);
childThread.Abort();
}
}
//This method runs once, and can't run at the same time as GetInformationProcess
public string GetSpecificInformation()
{
//This triggers InformationAcquiredCallback with a status of Cancelled
StopProcess();
if(childThread.IsAlive)
{
childThread.Join();
}
return PInvokeMethods.GetSpecificInformation();
}
public void StopProcess()
{
PInvokeMethods.SetCancelFlag(true);
}
}
使用当我打电话childThread.Join()整个应用程序嘎然而止(这是我所期待的UI,这就是罚款)和childThread也似乎停止,因为回调从来没有得到这个代码再次击中。
不过,如果我使用下面的代码来代替:
public string GetSpecificInformation()
{
//This triggers InformationAcquiredCallback with a status of Cancelled
StopProcess();
string s = "";
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
if(childThread.IsAlive)
{
childThread.Join();
}
s = PInvokeMethods.GetSpecificInformation();
}));
return s;
}
然后,一切都被击中预期和childThread确实完成,一切都很好,但显然我的字符串得到WaitCallback火灾前返回空并分配到它。
所以,我只是要吮吸它,并更改类,所以我使用QueueUserWorkItem和WaitCallback和触发事件来处理我的字符串返回?
在我的第一个方法中,是否有一些愚蠢的行为导致childThread阻塞?
还是有另一种策略或类,我应该使用,铭记它是.NET 3.5我在?
我花了近30年的时间试图阻止使用TThread.WaitFor()和其他类似的硬锁同步机制来产生死锁的Delphi开发人员。就在我想到我到某个地方时,Java和C#开发人员发现了join()。永无止境的噩梦。 – 2012-04-03 16:06:18
相信我,除非我绝望而且不在乎自己的深度,否则我不会触及任何这些;)那么你会推荐什么呢? – Nanhydrin 2012-04-03 16:12:38
如果你听Eric和其他人的话。 Invoke,BeginInvoke等,你不会错误的。不要在事件处理程序中等待 - 对其他线程有话要说的代理在主线程上触发时返回的信号采取行动。 – 2012-04-03 17:16:01