У меня есть программа, которая записывает файлы в общий сетевой ресурс с высокой скоростью, из нескольких (3) потоков одновременно.
После некоторого запуска (обычно непродолжительного) некоторые из этих потоков зависают. Используя Process Monitor, я вижу, что есть вызовы WriteFile и CloseFile, которые просто не имеют ответа.
На данный момент я вообще не могу завершить процесс, даже его удаление из диспетчера задач ничего не делает.
Интересно то, что это происходит, когда компьютер, на котором размещены общие папки, работает под управлением Windows Server 2008 (R2). Если я перенесу общие папки на компьютер с Windows 2003, я не увижу этих проблем. Кроме того, я вижу эту проблему только в том случае, если программа запускается на компьютере под управлением Windows Server 2008 (отличном от хоста общего ресурса).
Вот короткая программа, которая быстро воспроизводит проблему. Размер файлов в исходном каталоге варьируется от 1 до 20 МБ:
Imports System.IO
Imports System.Threading
Module Module1
Private m_sourceFiles As FileInfo()
Private m_targetDir As String
Sub Main(ByVal args As String())
Dim sourceDir As New DirectoryInfo(args(0))
m_sourceFiles = sourceDir.GetFiles()
m_targetDir = args(1)
For i As Integer = 0 To 2
ThreadPool.QueueUserWorkItem(AddressOf DoWork)
Next
Console.ReadLine()
End Sub
Private Const BUFFER_SIZE As Integer = (128 * 1024)
Private Sub DoWork(ByVal o As Object)
Console.WriteLine(Thread.CurrentThread.ManagedThreadId)
Dim random As New Random(Thread.CurrentThread.ManagedThreadId)
While True
Dim fileIndex As Integer = random.Next(m_sourceFiles.Count)
Dim sourceFile As FileInfo = m_sourceFiles(fileIndex)
Dim input As FileStream = sourceFile.OpenRead
Dim targetName As String = sourceFile.Name.Replace(sourceFile.Extension, random.Next(Integer.MaxValue) & sourceFile.Extension)
Dim targetPath As String = m_targetDir & "\" & targetName
Dim output As FileStream = File.Create(targetPath)
Dim bytes() As Byte = New Byte((BUFFER_SIZE) - 1) {}
Dim read As Integer = input.Read(bytes, 0, bytes.Length)
While read <> 0
output.Write(bytes, 0, read)
read = input.Read(bytes, 0, bytes.Length)
End While
output.Flush()
output.Close()
Console.WriteLine(Thread.CurrentThread.ManagedThreadId & " - " & targetName)
End While
End Sub
End Module