У меня есть программа, которая загружает / загружает файлы на онлайн-сервер, имеет функцию обратного вызова, чтобы сообщить о прогрессе и записать ее в текстовый файл. Программа построена со следующей структурой:
public void Upload(string source, string destination)
{
//Object containing Source and destination to pass to the threaded function
KeyValuePair<string, string> file = new KeyValuePair<string, string>(source, destination);
//Threading to make sure no blocking happens after calling upload Function
Thread t = new Thread(new ParameterizedThreadStart(amazonHandler.TUpload));
t.Start(file);
}
private void TUpload(object fileInfo)
{
KeyValuePair<string, string> file = (KeyValuePair<string, string>)fileInfo;
/*
Some Magic goes here,Checking The file and Authorizing Upload
*/
var ftiObject = new FtiObject ()
{ FileNameOnHDD = file.Key,
DestinationPath = file.Value,
//Has more data used for calculations.
};
//Threading to make sure progress gets callback gets called.
Thread t = new Thread(new ParameterizedThreadStart(amazonHandler.UploadOP));
t.Start(ftiObject);
//Signal used to stop progress untill uploadCompleted is called.
uploadChunkDoneSignal.WaitOne();
/*
Some Extra Code
*/
}
private void UploadOP(object ftiSentObject)
{
FtiObject ftiObject = (FtiObject)ftiSentObject;
/*
Some useless code to create the uri and prepare the ftiObject.
*/
// webClient.UploadFileAsync will open a thread that
// will upload the file and report
// progress/complete using registered callback functions.
webClient.UploadFileAsync(uri, "PUT", ftiObject.FileNameOnHDD, ftiObject);
}
Я получил обратный вызов, который зарегистрирован в событии UploadProgressChanged Webclient, однако он вызывается дважды за отправленный запрос.
void UploadProgressCallback(object sender, UploadProgressChangedEventArgs e)
{
FtiObject ftiObject = (FtiObject )e.UserState;
Logger.log(ftiObject.FileNameOnHDD, (double)e.BytesSent ,e.TotalBytesToSend);
}
Выход журнала:
Filename: C:\Text1.txt Uploaded:1024 TotalFileSize: 665241
Filename: C:\Text1.txt Uploaded:1024 TotalFileSize: 665241
Filename: C:\Text1.txt Uploaded:2048 TotalFileSize: 665241
Filename: C:\Text1.txt Uploaded:2048 TotalFileSize: 665241
Filename: C:\Text1.txt Uploaded:3072 TotalFileSize: 665241
Filename: C:\Text1.txt Uploaded:3072 TotalFileSize: 665241
Etc...
Я наблюдаю за сетевым трафиком с помощью наблюдателя, и отправляется только 1 запрос.
Некоторые, как я не могу понять, почему обратный вызов вызывается дважды, я сомневаюсь, что обратный вызов срабатывает при каждом открытом потоке (основная загрузка и загрузка TUpload), однако я не знаю, как проверить, является ли это причиной .
Примечание: причина многих / ** / Комментариев заключается в том, чтобы указать, что функции делают больше, чем просто открывают потоки, и используется потоки, чтобы убедиться, что блокировка не происходит (есть пара «Signal.WaitOne ()» вокруг кода для синхронизации)