2011-10-11 66 views
0

我想知道IM處理異常正確地在我的代碼是否因此希望有人能給我一些想法在我的代碼如下異常處理綜述

public IEnumerable<Job> GetAll() { 
     try { 
      return this._context.Jobs; 
     } catch (SqlException ex) { 
      //error so dispose of context 
      this.Dispose(); 
      //wrap and rethrow back to caller 
      throw new CentralRepositoryException("Error getting all jobs", ex); 
     } 

    } 

這個方法是我的業務邏輯的一部分,並呼籲上述

方法
public IEnumerable<Job> GetAllJobs() { 
     try { 
      return this._jobsRepository.GetAll(); 
     } catch (CentralRepositoryException ex) { 
      //logging code to go here 
      //throw back to caller 
      throw; 
     } catch (Exception ex) { 
      this._jobsRepository.Dispose(); 
      //logging code to go here 
      //throw simple exception to caller 
      throw new CentralRepositoryException("A general exception has occurred"); 
     } 
    } 

我的自定義異常

public class CentralRepositoryException : System.Exception { 
    public CentralRepositoryException(string message, Exception innerException) 
     : base(message, innerException) { 
    } 

    public CentralRepositoryException(string message){ 
    } 
} 
+0

這看起來像一個代碼審查問題! – AksharRoop

回答

0

你不應該簡單地重新拋出n當你鬆開堆棧跟蹤時出現異常。我可以看到你正在使用它們來處理對象,這應該在finally block

除非你能真正處理你不應該使用一個catch個例外,因爲你希望冒泡調用堆棧,使其可以固定 - 而不是隱藏。

+2

他使用throw;這保留了調用堆棧。 – PVitt

+0

@ m.edmondson在處理catch子句中的對象的原因是,如果沒有異常對象,即使配置仍然可用。有任何想法嗎? –

+0

@m。edmondson即時捕捉異常和centralrepositoryexception –

2

有幾個問題,這種方法:

  • 返回IEnumerable<T>會導致代碼的延遲執行。即使您返回IEnumerable<T>,在代碼中使用this._jobsRepository.GetAll().ToList();
  • 延遲執行導致錯誤處理程序不是,因爲在所有的代碼將運行延遲,並在客戶端上下文(即無論你正在使用它)被稱爲
  • 總結在using所有IDisposable對象塊

所以替代將是:

public IEnumerable<Job> GetAllJobs() { 
    try { 
     using(var jobsRepository = new JobsRepository()) // !!! Use Dependency Injection, etc 
     { 
       return jobsRepository .GetAll().ToList(); // !! NOTE: ToList() avoids delayed execution 

     } 
    } catch (CentralRepositoryException ex) { 
     //logging code to go here 
     //throw back to caller 
     throw; 
    } catch (Exception ex) { 
     //logging code to go here 
     //throw simple exception to caller 
     throw new CentralRepositoryException("A general exception has occurred", ex); // !!!!!! INCLUDE THE ORIGINAL ERROR !!!!!!! 
    } 
} 
+0

ahhh好的。在使用塊中包裝自動處理它們。我忘了 –

+0

實際上正在考慮它,我不想在每次通話後處理,因爲這破壞了上下文。因此,爲什麼我只有在有例外時才這樣做 –

0

這不是正確的使用處置()。如果你注意到你最終寫道:

this.Dispose(); 
this._jobsRepository.Dispose(); 

這兩個都指的是同一個對象。爲確保您只處理一次,它是聲明IDisposable的類的可重用性以調用dispose。

這意味着,如果你創建一個局部變量,你在using語句這樣做:

using(SomethingDisposable foo = new SomethingDisposable()) 
{ 
    //... 
} 

或顯式地處置:

SomethingDisposable foo = new SomethingDisposable(); 
try 
{ 
    //... 
} 
finally 
{ 
    ((IDisposable)foo).Dispose(); 
} 

如果創建一個字段,你讓你的類一次性太:

class MyDisposable : IDisposable 
{ 
    private SomethingDisposable foo = new SomethingDisposable(); 

    void IDisposable.Dispose() 
    { 
     foo.Dispose(); 
    } 
} 

如果你以這種方式對待你的IDisposables,那麼你的異常處理將不會對你的處置感到困惑。