2011-06-10 19 views
0

我已經構建了一個庫,它啓動一個線程來完成它的工作,並將一個WaitHandle返回給調用者。將AutoResetEvent對象包裝在受限制的WaitHandle中?

看着一個錯誤報告,我懷疑調用我的庫的代碼正在將返回的對象並將其轉換爲AutoResetEvent(它是)並提升標誌本身。這並不意味着要這樣做。

有沒有一種方法可以將AutoResetEvent對象與一個仍然可以WaitOne'd和WaitAny'd但只能由我的代碼引發的對象包裝?

謝謝。

+1

我不打算將此作爲答案添加,因爲它不直接解決您的問題......但更好的解決方案可能是返回錯誤報告並將其標記爲「預期行爲」。聽起來你的圖書館的消費者正在做他們不應該做的惡事。 – 2011-06-10 23:10:38

+0

我想過這個,但他們堅持認爲他們沒有這樣做。但是......我可以重新創建這個bug的唯一方法就是在錯誤的時間擅自舉辦這個活動。外交規則! – billpg 2011-06-10 23:23:28

+0

所以,你顯然得到了一些多線程代碼,並在你的機器上工作,但不能在另一個上工作。這很正常。 – 2011-06-11 00:12:02

回答

0

您可以創建一個從EventWaitHandle派生的新類,並覆蓋SetReset,以便它們不執行任何操作或拋出異常。實際上,您將不得不創建new實現,因爲SetReset不是虛擬的。當然,你必須創建你自己的,其他命名的方法。像MyInternalSetMyInternalReset。可能的,但我不會推薦這樣做。

相反,我會記錄客戶端不應該設置或重置事件,因爲這樣做會導致不可預知的行爲。

您可以創建一個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重載,以及。然後,您可以創建SetResetinternal實現,或者只需將您的代碼調用InternalHandle.Set即可。

我仍然認爲最好的行動方式是告訴客戶不要這樣做。但是,如果你必須防止它,上述應該工作。

+0

我想知道WaitHandle.WaitAny是否會利用我的WaitOne覆蓋。需要試驗! (感謝您的深入解答。) – billpg 2011-06-10 23:48:07