Можно ли инкапсулировать WebClient.DownloadDataAsync в одном классе? - PullRequest
0 голосов
/ 17 ноября 2010

Я пытаюсь инкапсулировать асинхронный метод загрузки WebClient, чтобы получить обновление индикатора выполнения, ожидая загрузки длинных файлов.Документация MSDN указывает, что FTPDownloadCompleted и FTPDownloadProgressChanged находятся в другом потоке, но никогда не запускаются.Может быть, я поступаю неправильно, но мне нужно избегать синхронизации событий, обратных вызовов и т. Д., Поэтому я решил попробовать этот маршрут.Мне особенно любопытно, почему события не запускаются, если они делегаты в другом потоке.

class downloadFTP
{ 
    public delegate void ProgressBarUpdate(Int32 val);
    ProgressBarUpdate progressBarUpdate;

    WebClient webClient;

    Int32 waitTime = 60;

    Double percentComplete = 0;

    Boolean transferComplete = false;
    public Boolean TransferComplete { get { return transferComplete; } }

    Byte[] downloadData = null;

    public Boolean DownLoadFTPFile(String filename, ProgressBarUpdate pbUpdate) 
    {
        Boolean result = false;

        progressBarUpdate = pbUpdate;
        AutoResetEvent waiter = new System.Threading.AutoResetEvent (false);
        webClient = new WebClient();
        webClient.Credentials = new NetworkCredential(user.userId, user.passWd);
        webClient.DownloadDataCompleted += new DownloadDataCompletedEventHandler(FTPDownloadCompleted);
        webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FTPDownloadProgressChanged);
        webClient.DownloadDataAsync(new Uri(ftpURL + "//" + filename),waiter);

        waiter.WaitOne(waitTime*1000);
        return TransferComplete;
    }

    private void FTPDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        percentComplete = e.ProgressPercentage;
    }

    private void FTPDownloadCompleted(object sender, DownloadDataCompletedEventArgs e)
    {
        downloadData = e.Result;
        transferComplete = true;
    }

1 Ответ

0 голосов
/ 17 ноября 2010

WebClient выполняет обратные вызовы для текущего SynchronizationContext (см. AsyncOperationManager.CreateOperation ).

Если текущий SynchronizationContext является циклом событий WinForms или WPF, то ваш *Метод 1007 * блокирует поток, и события не отображаются.Решение: удалите AutoResetEvent.

...