我测试了很多。但是我发现这两个没有缺点!
但请参阅接受的答案。
我在这里 读到调用
GetLastError托管代码是不安全的,因为框架可能会在内部“覆盖”最后一个错误。我从来没有遇到过任何明显的问题,GetLastError在我看来,.NET Framework 足够聪明,不会覆盖它。因此,我对该主题有几个问题:
- 该属性[DllImport("kernel32.dll", SetLastError = true)]是否SetLastError使框架存储错误代码以供使用Marshal.GetLastWin32Error()?
- 有没有一个简单的例子GetLastError不能给出正确的结果?
- 我真的必须使用Marshal.GetLastWin32Error()吗?
- 这个“问题”框架版本是否相关?
public class ForceFailure
{
    [DllImport("kernel32.dll")]
    static extern uint GetLastError();
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool SetVolumeLabel(string lpRootPathName, string lpVolumeName);
    public static void Main()
    {
        if (SetVolumeLabel("XYZ:\\", "My Imaginary Drive "))
            System.Console.WriteLine("It worked???");
        else
        {
            // the first last error check is fine here:
            System.Console.WriteLine(GetLastError());
            System.Console.WriteLine(Marshal.GetLastWin32Error());
        }
    }
}
产生错误:
if (SetVolumeLabel("XYZ:\\", "My Imaginary Drive "))
    Console.WriteLine("It worked???");
else
{
    // bad programming but ok GetlLastError is overwritten:
    Console.WriteLine(Marshal.GetLastWin32Error());
    try
    {
        using (new FileStream("sdsdafsdfsdfs sdsd ", FileMode.Open)) { }
    }
    catch { }
    Console.WriteLine(GetLastError());
}
if (SetVolumeLabel("XYZ:\\", "My Imaginary Drive "))
    Console.WriteLine("It worked???");
else
{
    // bad programming and Marshal.GetLastWin32Error() is overwritten as well:
    Console.WriteLine(GetLastError());
    try
    {
        using (new FileStream("sdsdafsdfsdfs sdsd ", FileMode.Open)) { }
    }
    catch { }
    Console.WriteLine(Marshal.GetLastWin32Error());
}
// turn off concurrent GC
GC.Collect(); // doesn't effect any of the candidates
Console.WriteLine(" -> " + GetLastError());
Console.WriteLine(" -> " + GetLastError());
Console.WriteLine(Marshal.GetLastWin32Error());
Console.WriteLine(Marshal.GetLastWin32Error());
// when you exchange them -> same behaviour just turned around
我看不出有什么区别!两者的行为相同,除了Marshal.GetLastWin32Error存储来自 App->CLR->WinApi 调用的结果以及GetLastError仅存储来自 App->WinApi 调用的结果。
垃圾收集似乎没有调用任何覆盖最后一个错误代码的 WinApi 函数
- GetLastError 是线程安全的。SetLastError 为每个调用它的线程存储一个错误代码。
- 从什么时候开始 GC 在我的线程中运行?