2012-09-08 57 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中实现这个包装器。