我已經構建了一個庫,它啓動一個線程來完成它的工作,並將一個WaitHandle返回給調用者。將AutoResetEvent對象包裝在受限制的WaitHandle中?
看着一個錯誤報告,我懷疑調用我的庫的代碼正在將返回的對象並將其轉換爲AutoResetEvent(它是)並提升標誌本身。這並不意味着要這樣做。
有沒有一種方法可以將AutoResetEvent對象與一個仍然可以WaitOne'd和WaitAny'd但只能由我的代碼引發的對象包裝?
謝謝。
我已經構建了一個庫,它啓動一個線程來完成它的工作,並將一個WaitHandle返回給調用者。將AutoResetEvent對象包裝在受限制的WaitHandle中?
看着一個錯誤報告,我懷疑調用我的庫的代碼正在將返回的對象並將其轉換爲AutoResetEvent(它是)並提升標誌本身。這並不意味着要這樣做。
有沒有一種方法可以將AutoResetEvent對象與一個仍然可以WaitOne'd和WaitAny'd但只能由我的代碼引發的對象包裝?
謝謝。
您可以創建一個從EventWaitHandle
派生的新類,並覆蓋Set
和Reset
,以便它們不執行任何操作或拋出異常。實際上,您將不得不創建new
實現,因爲Set
和Reset
不是虛擬的。當然,你必須創建你自己的,其他命名的方法。像MyInternalSet
和MyInternalReset
。可能的,但我不會推薦這樣做。
相反,我會記錄客戶端不應該設置或重置事件,因爲這樣做會導致不可預知的行爲。
您可以創建一個WaitHandle
派生類,該類將AutoResetEvent
保存爲internal
屬性。客戶端代碼將無法訪問它。喜歡的東西:
public class MyWaitHandle: WaitHandle
{
internal AutoResetEvent InternalEvent { get; private set; }
internal MyWaitHandle(AutoResetEvent event)
{
InternalEvent = event;
}
public override bool WaitOne(int32 timeout)
{
return InternalEvent.WaitOne();
}
}
你必須重寫保護Dispose(Boolean)
方法,這樣它會釋放該內部手柄,你會想其他WaitOne
重載,以及。然後,您可以創建Set
和Reset
的internal
實現,或者只需將您的代碼調用InternalHandle.Set
即可。
我仍然認爲最好的行動方式是告訴客戶不要這樣做。但是,如果你必須防止它,上述應該工作。
我想知道WaitHandle.WaitAny是否會利用我的WaitOne覆蓋。需要試驗! (感謝您的深入解答。) – billpg 2011-06-10 23:48:07
我不打算將此作爲答案添加,因爲它不直接解決您的問題......但更好的解決方案可能是返回錯誤報告並將其標記爲「預期行爲」。聽起來你的圖書館的消費者正在做他們不應該做的惡事。 – 2011-06-10 23:10:38
我想過這個,但他們堅持認爲他們沒有這樣做。但是......我可以重新創建這個bug的唯一方法就是在錯誤的時間擅自舉辦這個活動。外交規則! – billpg 2011-06-10 23:23:28
所以,你顯然得到了一些多線程代碼,並在你的機器上工作,但不能在另一個上工作。這很正常。 – 2011-06-11 00:12:02