我测试了很多。但我发现这两个没有缺点!
但请参阅已接受的答案。
I read
here http://blogs.msdn.com/b/adam_nathan/archive/2003/04/25/56643.aspx that calling
GetLastError
in managed code is unsafe because the Framework might internally "overwrite" the last error. I have never had any noticeable problems with
GetLastError
and it seems for me that the .NET Framework is smart enough not to overwrite it. Therefore I have a few questions on that topic:
- in
[DllImport("kernel32.dll", SetLastError = true)]
是否SetLastError
属性使框架存储错误代码以供使用Marshal.GetLastWin32Error()
?
- 有没有一个简单的例子
GetLastError
未能给出正确的结果?
- do I 真的有 to use
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());
}
}
}
Producing errors:
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 调用的结果。
Garbage Collection seems not to call any WinApi functions overwriting the last error code
- GetLastError 是线程安全的。 SetLastError 为每个调用它的线程存储一个错误代码。
- 从什么时候开始 GC 在我的线程中运行?