2015-04-01 56 views
1

有人能幫我找出這裏有什麼錯嗎?使用未分配的本地變量'訪問器

accessor.Dispose(); 

導致編譯器錯誤,但只在Read方法中。寫編譯罰款不讀這樣的IM困惑......

public bool Read(ref byte[] bytes) 
    { 
     MemoryMappedViewAccessor accessor; 
     Lock.WaitOne(); 
     try 
     {     
      accessor = Mmf.CreateViewAccessor(0, DataLength); 
      bytes = new byte[DataLength]; 
      accessor.ReadArray<byte>(0, bytes, 0, DataLength);     
     } 
     catch 
     { 
      return false; 
     } 
     finally 
     { 
      accessor.Dispose(); 
      Lock.ReleaseMutex(); 
     } 

     return true; 
    } 

    public bool Write(byte[] bytes) 
    { 
     MemoryMappedViewAccessor accessor; 
     Lock.WaitOne(); 
     try 
     { 
      DataLength = bytes.Length; 
      accessor = Mmf.CreateViewAccessor(0, bytes.Length); 
      accessor.WriteArray<byte>(0, bytes, 0, bytes.Length); 
     } 
     catch 
     { 
      return false; 
     } 
     finally 
     { 
      Dispose(); 
      Lock.ReleaseMutex(); 
     } 
     return true; 
    } 
+0

剛一說明:要調用,而不是'accessor.Dispose類的'的Dispose()'在'Write'方式方法,( );'。這可能會導致意想不到的行爲。 – Velox 2015-04-01 18:32:47

回答

2

這是可能的,一個例外是拋出try內,前accessor被分配一個值。某些方面,這可能會發生:

  1. 線程終止異常
  2. 內存不足例外分配新對象
  3. 在你分配給它的對象的構造函數的異常。

至於如何處理它;有兩個簡單的選項:

  1. 對該變量使用using,以便編譯器可以爲您完成所有工作。
  2. accessor初始化爲null,並僅在非空時處置它。
1

問題是您正在使用該變量,但如果出現異常,則可能無法初始化該變量。

我會重構這個使用using塊來代替:

public bool Read(ref byte[] bytes) 
{ 
    Lock.WaitOne(); 
    try 
    {     
     using (MemoryMappedViewAccessor accessor = Mmf.CreateViewAccessor(0, DataLength)) 
     { 
      bytes = new byte[DataLength]; 
      accessor.ReadArray<byte>(0, bytes, 0, DataLength);     
      return true; 
     } 
    } 
    catch 
    { 
     return false; 
    } 
    finally 
    { 
     Lock.ReleaseMutex(); 
    } 
} 

另一種方法是初始化到null在線,然後檢查調用Dispose之前null,但這需要更多的代碼,作爲一個使用塊來簡化整個代碼。

+0

那麼即使在使用塊中發生異常,這個例子中的catch也會被執行嗎? – xnp 2015-04-01 19:48:28

+0

@ user1778306是的。 – 2015-04-01 20:22:09

1

您應該在ReadWrite方法中都得到相同的錯誤,但Write方法中的代碼是錯誤的,因此它避免了錯誤。

Write您有:

finally 
    { 
     Dispose(); 
     Lock.ReleaseMutex(); 
    } 

但應該是:

finally 
    { 
     accessor.Dispose(); 
     Lock.ReleaseMutex(); 
    } 

編譯器錯誤是因爲它有可能在finally塊落得沒有值分配給accessor 。如果在創建分配給變量的對象時發生異常,就會發生這種情況。

要修復編譯器錯誤,您可以在try塊前設置null值到accessor變量:

MemoryMappedViewAccessor accessor = null; 

然後在finally塊你檢查,如果你有一個實際的對象進行處理:

finally 
    { 
     if (accessor != null) { 
      accessor.Dispose(); 
     } 
     Lock.ReleaseMutex(); 
    } 
0

e只對decarred變量MemoryMappedViewAccessor accessor;然後嘗試在最後的Read塊中使用它。所以你得到編譯器error.u

但在寫你只是調用dispose(不accessor.Dispose())所以沒有錯誤那裏。可能是打字錯誤?

您需要在finally塊之前初始化訪問器。可能需要最終修改寫入。

閱讀:

finally 
     { 
      accessor.Dispose(); 
      Lock.ReleaseMutex(); 
     } 

寫:

finally 
     { 
      Dispose(); 
      Lock.ReleaseMutex(); 
     }