2009-07-14 33 views
0

我有一個C#程序,它使用內置於SeralPort類中的 與串行設備進行通信。但是,我想要執行異步寫入 併爲此我使用BaseStream.BeginWrite()。在異步回調 我調用BaseStream.EndWrite()。所有這些工作正常。但是,有時 我想在BeginWrite()完成之前關閉一個端口,但只要BeginWrite()掛起,調用 Close()會導致它掛起。 我曾嘗試調用EndWrite(),但如果BeginWrite() 處於掛起狀態,那也會掛起。我如何殺死BeginWrite()線程?出現 是沒有BaseStream.Abort()或類似的。使用BaseStream強制終止串行COM端口IO應用程序中的BeginWrite

感謝

回答

1

我找到了一個方法,但它有點hackish。該方法關閉端口並中止,但在該過程中拋出了一些例外情況。基本上,我使用反射來獲取設備的文件句柄如下:

object p = _port.BaseStream.GetType().GetField("_handle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField).GetValue(_port.BaseStream); 
IntPtr hFile = (IntPtr)p.GetType().GetField("handle", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField).GetValue(p); 

_port是打開的SerialPort。然後我關閉該文件如下

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
static extern bool CloseHandle(IntPtr hFile); 
CloseHandle(hFile); 

有可能是通過調用在BaseStream私有方法一個更好的方法,但這是一種方式:)


0

我也認爲你無法取消操作,如果Stream.Close()不會做的伎倆。 EndWrite()在設計上,在同一線程上的BeginWrite()EndWrite()的序列與調用同步功能相同。

實際上,甚至可能沒有線程在運行。該操作可能會在內部使用IO完成端口,並僅在線程池線程上觸發回調。 (這是我查看過的東西以來的一段時間)

但是你可以做的是'放棄'流,在你的代碼中設置一個標誌,當回調到達時,如果標誌被設置,關閉流。請記住在國旗附近放一個lock或讓它volatile

+0

我放棄了流是罰款。但是,嘗試重新打開會導致失敗。我懷疑這可能無法完成。有趣的是,我有一個商業的win32控制檯應用程序,它可以做同樣的事情並且工作正常。 謝謝。 – HiteshP 2009-07-16 14:22:54