Может стоить посмотреть базовый класс BackgroundWorker
, а также пул потоков:
ThreadPool.QueueUserWorkItem(delegate
{
s3.PutFile ("myId", File.OpenRead(@"C:\myFile1"));
});
Это в основном то, что вы будете делать с шаблоном Action / BeginInvoke. С BeginInvoke вы дополнительно получаете IAsyncResult
, на который вы можете вызвать .WaitOne()
, чтобы заблокировать текущий поток до завершения операции, если вам это нужно. Вы бы активировали новый BeginInvoke
для каждого файла, который хотите сохранить.
Если вам нужно делать это часто, более сложной версией может быть использование очереди в сочетании с BackgroundWorker, например ::
public sealed class S3StoreLikePutFileWorker<TYourData> : BackgroundWorker
{
private AutoResetEvent WakeUpEvent = new AutoResetEvent(false);
private Queue<TYourData> DataQueue = new Queue<TYourData>();
private volatile bool StopWork = false;
public void PutFile(TYourData dataToWrite)
{
DataQueue.Enqueue(dataToWrite);
WakeUpEvent.Set();
}
public void Close()
{
StopWork = true;
WakeUpEvent.Set();
}
private override void OnDoWork(DoWorkEventArgs e)
{
do
{
// sleep until there is something to do
WakeUpEvent.WaitOne();
if(StopWork) break;
// Write data, if available
while(DataQueue.Count > 0)
{
TYourData yourDataToWrite = DataQueue.Dequeue();
// write data to file
}
}
while(!StopWork);
}
}
В зависимости от того, сколько сложности вам нужно.
BackgroundWorker поддерживает обратную связь о ходе выполнения (установите WorkerReportsProgress = true;
в конструкторе), и вы также можете добавить пользовательское событие для сообщения об ошибках, если это необходимо:
// create a custom EventArgs class that provides the information you need
public sealed class MyEventArgs : EventArgs {
// Add information about the file
}
// ... define the event in the worker class ...
public event EventHandler<MyEventArgs> ErrorOccured;
// ... call it in the worker class (if needed) ...
if(ErrorOccured != null) ErrorOccured(this, new MyEventArgs(/*...*/));