這可能是一個愚蠢的問題,如果這已經回答了其他地方,那麼我真的很感激,如果我的搜索沒有止跌回升有人可以點我給它任何明確的。的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