【发布时间】:2017-09-23 14:10:48
【问题描述】:
我正在创建一个创建随机文件的简单函数。为了线程安全,它会在重试循环中创建文件,如果文件存在,它会再次尝试。
while (true)
{
fileName = NewTempFileName(prefix, suffix, directory);
if (File.Exists(fileName))
{
continue;
}
try
{
// Create the file, and close it immediately
using (var stream = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
{
break;
}
}
catch (IOException e)
{
// If the error was because the file exists, try again
if ((e.HResult & 0xFFFF) == 0x00000050)
{
continue;
}
// else rethrow it
throw;
}
}
根据 MSDN,HResult 值来自 COM,这似乎表明它只能在 Windows 上工作,它是specifically lists them as "Win32 codes"。但这是在一个针对 .NET Standard 的库中,理想情况下它应该适用于 every platform .NET Standard supports。
我想知道的是我是否可以依靠上述使用 HResult 的值来跨平台的方法? documentation 在这一点上不清楚。
如果不是,我如何确定在其他平台上期望的 HResult 值?
注意: 有一个类似的问题Does .NET define common HRESULT values?,但在 .NET 标准(以及对 .NET 的跨平台支持)存在之前就有人问过了,所以我不能依赖这个答案目的。
目前,我们的代码库仅使用:
- 0x00000020 - ERROR_SHARING_VIOLATION
- 0x00000021 - ERROR_LOCK_VIOLATION
- 0x00000050 - ERROR_FILE_EXISTS
我们的目标是 .NET Standard 1.5。
注意:虽然接受的答案确实满足我在这里提出的问题,但我有一个后续问题How do I make catching generic IOExceptions reliably portable across platforms?
【问题讨论】:
-
我想您必须更具体地了解您想要依赖的场景或特定错误代码。有很多地方使用了预定义代码列表(您可以搜索
hresults.csin CoreCLR 和 fullfx 参考源代码),在某些情况下还有标准化函数like this one for file errors。 -
谢谢马丁。我添加了我目前感兴趣的 3 个错误。不过,我有点希望得到更一般的答案。通常,我们只对文件 IO 错误感兴趣。
-
您可能希望链接到 this documentation 而不是 msdn 链接,因为它是官方 .net 标准 1.5 API 文档。 (可以肯定是MSDN的复制粘贴,不过点对点就好)
-
我更新了链接。我还问了一个后续问题stackoverflow.com/questions/46382637
-
@MartinUllrich - 您能否具体回答
ERROR_SHARING_VIOLATION和ERROR_LOCK_VIOLATION是否是跨平台的?我尝试分析您链接的代码,但似乎找不到定义这些常量的实际位置。我们有一个效率较低的后备实现,但我不希望使用它,或者至少将其限制在不太流行的平台上。
标签: c# .net .net-standard hresult