2014-05-06 70 views
0

我有點沮喪,試圖找出最好的路線是用try-catch語句處理C#中的異常。我想擁有代碼,所以如果試圖打開一個註冊表項引發異常,那麼它會移動到下一個註冊表項。我能想到的唯一方法就是通過將每個函數調用封裝在try-catch語句中,但對我來說,這似乎有很長的路要走。更少的try-catch語句?

  • 有沒有其他方法可以做到這一點?
  • 你可以擁有單個try-catch語句中的所有代碼,並且當發生異常時,是否將它移動到下一行代碼中(如step over)?
  • 我知道這可能是一個否,但如果變量設置在參數中,可以使用ScanSubKey函數檢查異常嗎?

沒有的try-catch語句

ScanSubKey(Registry.ClassesRoot); 
ScanSubKey(Registry.LocalMachine.OpenSubKey("SOFTWARE")); 
ScanSubKey(Registry.CurrentUser.OpenSubKey("SOFTWARE")); 
if (Is64BitOS) 
{ 
    ScanSubKey(Registry.ClassesRoot.OpenSubKey("Wow6432Node")); 
    ScanSubKey(Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node")); 
    ScanSubKey(Registry.CurrentUser.OpenSubKey("SOFTWARE\\Wow6432Node")); 
} 

try { 
    ScanSubKey(Registry.ClassesRoot); 
} 
catch (Exception ex) { 
    Debug.WriteLine("The following error occurred opening a registry key: " + ex.Message); 
} 
try { 
    ScanSubKey(Registry.LocalMachine.OpenSubKey("SOFTWARE")); 
} 
catch (Exception ex) { 
    Debug.WriteLine("The following error occurred opening a registry key: " + ex.Message); 
} 
try { 
    ScanSubKey(Registry.CurrentUser.OpenSubKey("SOFTWARE")); 
} 
catch (Exception ex) { 
    Debug.WriteLine("The following error occurred opening a registry key: " + ex.Message); 
} 

if (Is64BitOS) 
{ 
    try { 
     ScanSubKey(Registry.ClassesRoot.OpenSubKey("Wow6432Node")); 
    } 
    catch (Exception ex) { 
     Debug.WriteLine("The following error occurred opening a registry key: " + ex.Message); 
    } 
    try { 
     ScanSubKey(Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node")); 
    } 
    catch (Exception ex) { 
     Debug.WriteLine("The following error occurred opening a registry key: " + ex.Message); 
    } 
    try { 
     ScanSubKey(Registry.CurrentUser.OpenSubKey("SOFTWARE\\Wow6432Node")); 
    } 
    catch (Exception ex) { 
     Debug.WriteLine("The following error occurred opening a registry key: " + ex.Message); 
    } 
} 
+0

AFAIK這是不可能的,請參閱[這裏](http://social.msdn.microsoft.com/Forums/en-US/2294d2ce-e6ae-4152-b022-61aa2ae9372d/trycatchcontinue-with-next-line-在嘗試塊?forum = Vsexpressvcs) – AlphaDelta

回答

0

我把這叫做 「執行人」:

public static void Execute(Action action) 
    { 
     try 
     { 
      action(); 
     } 
     catch (Exception ex) 
     { 
     } 
    } 

,然後使用它:

Execute(() => ScanSubKey(Registry.ClassesRoot)); 
+0

讓我想起VB的'ON ERROR RESUME NEXT' :-( – Maarten

+0

@Maarten我不會認爲這是好的做法 - 但它完成了工作! – toATwork

+0

我喜歡這個技巧。非常聰明! – ub3rst4r

1

也許這將是一個更好的方法:

public bool TryOpenRegKey(RegistryKey regKey, string subKey = default(string)) 
{ 
    try 
    { 
    if (string.IsNullOrWhiteSpace(subKey)) 
     ScanSubKey(regKey); 
    else 
     ScanSubKey(regKey.OpenSubKey(subKey)); 

    return true; 
    } 
    catch(Exception ex) 
    { 
    Debug.WriteLine("The following error occurred opening a registry key: " + ex.Message); 
    return false; 
    } 
} 

然後:

TryOpenRegKey(Registry.ClassesRoot); 
TryOpenRegKey(Registry.LocalMachine, "SOFTWARE"); 
TryOpenRegKey(Registry.CurrentUser, "SOFTWARE"); 

if (Is64BitOS) 
{ 
    TryOpenRegKey(Registry.ClassesRoot, "Wow6432Node"); 
    TryOpenRegKey(Registry.LocalMachine, "SOFTWARE\\Wow6432Node"); 
    TryOpenRegKey(Registry.CurrentUser, "SOFTWARE\\Wow6432Node"); 
} 
0

你有沒有考慮把一個try/catch的ScanSubKey函數內本身並在發生錯誤時返回?

1

創建一個新方法TryScanSubKey。那麼你的代碼看起來又幹淨:

TryScanSubKey(Registry.ClassesRoot); 
TryScanSubKey(Registry.LocalMachine.OpenSubKey("SOFTWARE")); 
TryScanSubKey(Registry.CurrentUser.OpenSubKey("SOFTWARE")); 
if (Is64BitOS) 
{ 
    TryScanSubKey(Registry.ClassesRoot.OpenSubKey("Wow6432Node")); 
    TryScanSubKey(Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node")); 
    TryScanSubKey(Registry.CurrentUser.OpenSubKey("SOFTWARE\\Wow6432Node")); 
} 

TryScanSubKey的實施應該是顯而易見的,但是,爲了完整起見,在這裏它是:

void TryScanSubKey(RegistryKey key) 
{ 
    try 
    { 
     ScanSubKey(key); 
    } 
    catch (Exception ex) 
    { 
     Debug.WriteLine("The following error occurred opening a registry key: " + ex.Message); 
    } 
} 

需要注意的是,一般,吞嚥的誤差不好的做法,併吞咽全部錯誤仍然更糟糕。所以請考慮(至少)用更具體的東西代替catch (Exception ex),例如catch (TheSpecificExceptionThrownByScanSubKey ex)

+0

如果因爲如果註冊表項在發送到TryScanSubKey之前無法打開,那麼這樣做是否仍然會導致程序失敗,那麼有沒有什麼可以趕上它? – ub3rst4r

+0

@ ub3rst4r:[ RegistryKey.OpenSubKey](http://msdn.microsoft.com/de-de/library/z9f66s0a(v = vs.110)。aspx)將不會拋出一個異常,如果該鍵缺失 - 它只是返回null,這可以很容易地在TryScanSubKey中檢查。如果操作由於某些其他原因而失敗,那麼程序*應該*失敗,因爲在這種情況下,註冊表中的某些內容被嚴重破壞。 – Heinzi

+0

如果這是由於對子密鑰的權限造成的? – ub3rst4r