2012-09-08 85 views
0

我想懇請有關在C#中的良好的編程習慣你的建議,當談到定義變量,爲他們分配空間,初始化它們,然後經過清理妥善清理一切。變量聲明,初始化和unamanaged內存分配

我面對的時刻的問題是,我有,它使用非託管API函數,其結果也不受管理的訪問存儲器(用於封送)的功能。我希望在退出之前使該功能保持清潔並妥善處理所有內容。事情是,所有的實際工作都在try-catch塊內完成。這意味着我無法清理中的所有內容終於區塊。

我所做的就是聲明的所有變量,保留存儲器他們在最後塊進入的功能,然後乾淨的一切行動(靠近手柄,釋放內存,...)之後初始化它們。

都好,但我也想有變量聲明,初始化和內存分配在做過嘗試塊(東西初始化例如數組或內存中分配空間時,也可能會出錯或上帝知道在哪裏)。唯一想到的是嵌套兩個try-catch塊。這是好的還是你會提出其他建議?

這是我到目前爲止有:

//Declare variables, allocate memory, initialize variables. 
........ 
try 
{ 
    //Do actual work - write to file and read from a file in my case 
    ......... 
} 
catch (Exception exc) 
{ 
    //Exception handler for file write/read errors 
} 
finally 
{ 
    //Clean up (release handles, free memory,...) 
} 

而且這裏是我的想法:

try 
{ 
    //Declare variables, allocate memory, initialize variables. 
    ........ 
    try 
    { 
     //Do actual work - write to file and read from a file in my case 
     ......... 
    } 
    catch (Exception exc) 
    { 
     //Exception handler for file write/read errors 
    } 
} 
catch (Exception exc_1) 
{ 
    //Exception handler for variable declaration, initialization, memory allocation errors 
} 
finally 
{ 
    //Clean up (release handles, free memory,...) 
} 

預先感謝您的幫助!

乾杯!

回答

1

您可以依次調用Dispose方法實現IDisposable接口。

或者作爲最佳實踐使用塊using

using (var variable = .....) 
{ 

... 

} 

使用塊的特殊性在於,調用Dispose方法在治療結束。

例如,如果您使用SqlConnection

var(var connection = new SqlConnection("....")) 
{ 
.... 

} 

就在這個代碼就足夠了

鏈接:http://msdn.microsoft.com/fr-fr/library/vstudio/system.idisposable.aspx

鏈接:http://msdn.microsoft.com/fr-fr/library/yh598w02%28v=vs.80%29.aspx

+0

這對我來說不行,我想。我想在最外面嘗試的一些例子: 'NativeOverlapped HidOverlapped = new NativeOverlapped();' 'IntPtr eventObject = CreateEvent(IntPtr.Zero,false,false,「」);' 'IntPtr nonManagedOverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(HidOverlapped));' 'Marshal.StructureToPtr(HidOverlapped,nonManagedOverlapped,false);' 我也正在初始化我的數組元素之一。爲了安全起見,我還必須假設在執行此操作時可能發生錯誤(例如IndexOutOfBounds異常)。 有什麼想法? – EEALNT

+0

如何使用單獨的函數來完成工作(讀取和寫入文件)?這樣這個新函數將有它自己的try和catch塊。 但是,如果拋出異常並由被調用函數中的catch塊處理,程序是否會返回調用者函數? – EEALNT

+0

1你可以使用2 set使用block設置你的nonManagedOverlapped來添加try catch,這很好 –

0

問題與方法是變量超出範圍在終於(和趕)

try 
    { 
     string testString; 
    } 
    catch (Exception ex) 
    { 
    } 
    finally 
    { 
     // testString is not in scope 
    } 

你關注的是,該聲明可能會引發一個運行時錯誤?

基於評論OP不知道初始化可以與聲明分開。

List<string> testLString;   
    try 
    { 
     testLString = new List<string>(); 
    } 
    catch (Exception ex) 
    { 
    } 
    finally 
    { 
     testLString = null; 
    } 

我不同意你關心的聲明可能會引發運行時錯誤。
它只是聲明。

+0

這正是我關心的問題。而且由於我也在初始化變量(不僅僅是聲明它們),我擔心可能會彈出一個錯誤。 簡單來說,我想將這個功能分爲兩部分: 1)準備工作所需的所有東西(聲明和初始化變量,結構和內容;在內存的非託管部分準備所有內容,.. ) 2)做實際工作 我希望有兩個部分「覆蓋」例外。 – EEALNT

+0

你知道你可以單獨初始化聲明嗎? – Paparazzi

0

您可以根據需要嵌套儘可能多的try...catch結構。這是讓代碼爲自己的清理負責的好方法。

還可以考慮使用一個結構,只是tryfinally代碼總是需要清理,無論它去好不好:

try { 

    // do something here 

    // declare some variable 
    try { 
    // allocate space for variable 
    // do something with that variable 
    } fincally { 
    // deallocate space for variable 
    } 

    // do something more here 

} catch(Exception ex) { 
    // handle the exception here 
} 

你應該嘗試使用異常類,是具體的可能的話,你可以在同一結構中使用不同類型的捕捉不同的異常:

try { 
    // do some i/o 
} catch (IOException ex) { 
    // here you know that it was actually the i/o that failed 
} catch (Exception ex) { 
    // here is for catching anything else that might have failed 
} 
0

我建議你創建一個單獨的類型,其包裝與非託管API的所有通信,管理米emory等。它實現了IDisposable接口,其實現負責清理所有非託管資源。如果你在Windows上,最簡單的方法就是在C++/CLI中實現這個包裝器。