Ответ 1
Попробуйте монитор процесса. Он покажет вам, какой пользователь обращается к файлу и к конкретному коду ошибки Windows, который возвращается. Затем вы сможете увидеть, почему он работает для некоторых файлов, а не других.
Это немного сложно, так что медведь со мной...
У меня есть простой небольшой метод:
Public Overloads Shared Function DoStuff(ByVal path As String) As Boolean
If Not IO.File.Exists(ipath) Then Throw New ArgumentException
Dim result As Boolean
Using fs As FileStream = New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
' do stuff here, details are not important
fs.Close()
End Using
Return result
End Function
Я ценю, что метод не показывает, как используется поток, но детали неактуальны, как я объясню ниже.
Этот метод помещается в библиотеке классов; Помощник, который мы ссылаемся в целом ряде других проектов. Понятно, что в большинстве случаев этот код должен выглядеть хорошо в предположении, что путь действителен, доступен и т.д.
Теперь проблема. У меня есть сервисная библиотека WCF, которая ссылается и использует вышеупомянутый метод в сборке помощников. Библиотека обслуживания WCF размещается в службе Windows, которая, в свою очередь, находится на одном из наших серверов. Служба WCF имеет операцию, которая получает UNC-путь для файла, и во время обычного потока вызывает метод выше в классе помощников.
Путь, который я отправляю, предназначен для файла, на общем ресурсе, в нашей сети. Строка "Использование fs As..." завершается со следующим исключением:
System.UnauthorizedAccessException: доступ к пути "Мой путь к файлу указан здесь" отклонен. в System.IO.__ Error.WinIOError(Int32 errorCode, String maybeFullPath) в System.IO.FileStream.Init(путь String, режим FileMode, доступ к FileAccess, права Int32, логические значения useRights, общий ресурс FileShare, параметры Int32 bufferSize, FileOptions, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath) в System.IO.FileStream..ctor(путь String, режим FileMode, доступ к FileAccess, общий ресурс FileShare, параметры Int32 bufferSize, FileOptions, String msgPath, Boolean bFromProxy) в System.IO.FileStream..ctor(String path, FileMode mode) в MyHelperAssemblyName.DoStuff(String filePath) в остальной части исключения - это трассировка стека, указывающая на метод, сборку, службу wcf и т.д.
Теперь, список вещей, которые я пытался диагностировать проблему (включая тупо очевидные шаги):
EDIT 2011-06-27 10: 23GMT. Раздраженный тем, что служба работала, я вытащил WcfStorm, который у меня остался в течение выходных. Результаты показывались с пятницы, показывая, что живая служба потерпела неудачу. Я возмущаюсь тем же запросом → Он работал... Меня сейчас больше раздражает, потому что у меня нет реальных средств для отслеживания проблемы
Итак, служба работает корректно. У кого-нибудь есть идеи, что могло бы вызвать такой прерывистый провал? Меня уверяют коллеги, что ничто не изменилось за выходные (по крайней мере, не вручную). Расстроенный...
Попробуйте монитор процесса. Он покажет вам, какой пользователь обращается к файлу и к конкретному коду ошибки Windows, который возвращается. Затем вы сможете увидеть, почему он работает для некоторых файлов, а не других.
У меня было что-то подобное, когда мой код обращался к новому файлу, который еще не был полностью записан на диск. Поэтому ожидания нескольких миллисекунд решили это для меня. Возможно ли, что вы пытаетесь прочитать этот поток до его полной записи на диск?
Использует ли ваша служба WCF олицетворение?
Это объясняет, почему новая служба Windows может выполнять действие, но служба WCF не может. Новая служба аутентифицируется непосредственно против NAS. Если в старой службе WCF выдавал себя за вызывающего абонента, клиентский компьютер аутентифицирует пользователя, их токен передается вашей службе WCF, которая, в свою очередь, передает токен безопасности NAS, и вы попадаете в double hop.
Вы можете заставить активный контекст безопасности вернуться к учетной записи службы, например this:
using (WindowsIdentity.Impersontate(IntPtr.Zero))
{
DoStuff();
}
Конечно, это не объясняет, почему он мог работать с перерывами. Но это объясняет, что служба WCF работает при локальном вызове на машине, которая ее размещает, но не с удаленной клиентской машины.
У меня есть несколько догадок.
Вы пытались установить 'FileAccess.Read' и/или 'FileShare.Read' в 'ReadWrite'?
Кроме того, возможно ли, что это предупреждение может быть фактором? Из http://msdn.microsoft.com/en-us/library/5h0z48dh.aspx:
Внимание!
При компиляции набора символов с определенной культурной обстановкой и извлекать те же символы с помощью различные культурные условия, символы могут не интерпретироваться, и может стать причиной исключения выброшены.