我测试了很多。但是我发现这两个没有缺点!
但请参阅接受的答案。
我在这里 读到调用
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 在我的线程中运行?