Это небольшая проблема архитектуры и кода. У меня много исходных URL-адресов, содержащих огромные файлы, которые приходят от разных клиентов, которые я должен загрузить и сохранить в файловой системе.
У меня есть аппаратные ограничения на ОЗУ. Поэтому я хочу буферизовать каждый поток кусками байтов, и я думаю, что будет хорошей идеей инициировать один поток для каждой загрузки потока.
Я добавил код для запуска потока / задачи с помощью Task Parallel Библиотека как таковая:
public Task RunTask(Action action)
{
Task task = Task.Run(action);
return task;
}
и я передаю для параметра действия следующий метод:
public void DownloadFileThroughWebStream(WebClient webClient, Uri src, string dest, long buffersize)
{
Stream stream = webClient.OpenRead(src);
byte[] buffer = new byte[buffersize];
int len;
using (BufferedStream bufferedStream = new BufferedStream(stream))
{
using (FileStream fileStream = new FileStream(Path.GetFullPath(dest), FileMode.Create, FileAccess.Write))
{
while ((len = stream.Read(buffer, 0, buffer.Length)) > 0)
{
fileStream.Write(buffer, 0, len);
fileStream.Flush();
}
}
}
}
И я в целях тестирования пытаюсь загрузить некоторые ресурсы из http uri, как, инициируя поток / задача для каждого специфика c скачать:
[Test]
public async Task DownloadSomeStream()
{
Uri uri = new Uri("http://mirrors.standaloneinstaller.com/video-sample/metaxas-keller-Bell.mpeg");
List<Uri> streams = new List<Uri> { uri, uri, uri};
List<Task> tasks = new List<Task>();
var path = "C:\\TMP\\";
//Create task for each of the streams from uri
int c = 1;
foreach (var uri in streams)
{
WebClient webClient = new WebClient();
Task task = taskInitiator.RunTask(() => DownloadFileThroughWebStream(webClient, uri, Path.Combine(path,"File"+c), 8192));
tasks.Add(task);
c++;
}
Task allTasksHaveCompleted = Task.WhenAll(tasks);
await allTasksHaveCompleted;
}
Я получаю следующее исключение:
System.IO.IOException: 'The process cannot access the file 'D:\TMP\File4' because it is being used by another process'
в строке:
using (FileStream fileStream = new FileStream(Path.GetFullPath(dest), FileMode.Create, FileAccess.Write))
Итак, есть две вещи, которые я не понимаю с этим исключением:
Почему нельзя писать? и как другой процесс распределяет файл?
Почему он хочет сохранить file4
, когда я только добавил 3 URL, поэтому у меня должны быть только файлы: file1, file2, and file3
?
Кроме того, другие вопросы, которые могут быть полезны для размышления:
Правильно ли я подхожу к тому, что я делаю в отношении того, что я хочешь добиться? Правильно ли я выполняю инициации задач с помощью библиотеки параллельных задач?
Любые советы и рекомендации, лучшие практики и т. Д. c.?