Как определить HResult для системы.ИО.IOException?
Система.Исключение.Свойство HResult защищено. Как я могу заглянуть внутрь исключения и получить HResult, не прибегая к отражению или другим уродливым Хак?
ситуация такая:
Я хочу написать инструмент резервного копирования, который открывает и читает файлы в системе.
Я открываю файл с помощью FileAccess.Чтение и файлообмен.ReadWrite, согласно данное руководство, потому что мне все равно, открыт ли файл для записи в то время, когда я его читаю.
в некоторых случаях, когда файл, который я читаю, открыт другим приложением, системой.ИО.FileStream.Метод Read () создает систему.ИО.IOException, "процесс не может получить доступ к файлу, потому что другой процесс заблокировал часть файла". Это ошибка 33, или Я думаю HResult 0x80070021. [редактировать: я считаю, что это может быть возвращено, когда другой процесс вызывает LockFileEx для блокировки диапазона байтов в файле.]
Я хотел бы сделать паузу и повторите попытку, когда я получу эту ошибку. Я думаю,что это подходящее решение. Если процесс блокировки быстро освобождает блокировку диапазона байтов, я могу продолжить чтение файла.
Как я могу отличить исключение IOException по этой причине от других? Я могу думать о таких способах:
- личное отражение-не хочу этого делать. Перф будет вонять.
- вызов исключения.ToString() и парсить строку. Чувствую себя избитым. Не будет работать в версиях i18n.
Мне не нравятся эти варианты. Разве нет лучшего, более чистого способа?
Я просто искал вокруг и нашел
5 ответов
для .Net Framework 4.5 и выше вы можете использовать Exception.HResult
свойства:
int hr = ex.HResult;
для более старых версий, вы можете использовать Marshal.GetHRForException
чтобы вернуть HResult, но это имеет значительные побочные эффекты и не рекомендуется:
int hr = Marshal.GetHRForException(ex);
вы также можете использовать ISerializable
интерфейс:
static class IOExceptionExtensions
{
public static int GetHResult(this IOException ex)
{
var info = new SerializationInfo(typeof (IOException), new FormatterConverter());
ex.GetObjectData(info, new StreamingContext());
return info.GetInt32("HResult");
}
}
тут CanRead
свойства помочь в этом случае?
то есть call CanRead
, Если это возвращает true, вызов Read()
вы профилировали любой из этих случаев? Я бы предположил, что метод отражения не так уж медленен, особенно по отношению ко всем другим работам, которые будет делать ваше приложение, и как часто это исключение может произойти.
Если это окажется узким местом, вы можете изучить кэширование некоторых операций отражения или создать динамический IL для извлечения свойства.