У меня есть программа, которая записывает файлы в сетевой ресурс с высокой скоростью из нескольких (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