将 DownloadDataAsync 与 Cookie 感知 Web 客户端结合使用以获取更新进度

本文关键字:获取 更新 结合 DownloadDataAsync Cookie 感知 客户端 Web | 更新日期: 2023-09-27 18:31:16

我正在使用带有CookieContainer的Web客户端从Web服务(Sharepoint)下载数据。

我想下载数据异步,以便下载多个文档,并在下载每个文档时更新单个进度条。非异步版本 - 下载数据不发送进度更新。

  1. 如何让异步版本在文档中等待。二进制数据 = xx 行,然后继续下一个文档?
  2. 如何从 DownloadFileCompleted 事件中获取字节数组?
  3. 如何在不使用DoEvents的情况下将更改应用于进度条?

    分部类 Form(){ void Main() { 列表网址=新列表(); 网址。添加("xxxxxxx");从某个地方获取它们

        for (int i = 0; i < urls.Count; i++)
        {
            var doc = new Document();
            doc.BinaryData = DocumentAsArray(urls.ElementAt(i));
            entities.AddToDocument(doc);
        }
    }
    public byte[] DocumentAsArray(string URL)
    {
        byte[] @return = null;
        using (CookieAwareWebClient client = new CookieAwareWebClient())
        {
            client.CookieContainer = spAuthentication.CookieContainer;
            // Assign the events to capture the progress percentage
            client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
            client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
            client.DownloadDataAsync(new Uri(URL));
        }
        return @return;
    }
    void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        progressBarControlFile.Position = e.ProgressPercentage;
        var newPc = string.Format("Downloaded {0} %", e.ProgressPercentage);
        labelControlFile.Text = newPc;
        Application.DoEvents();
    }
    void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
        progressBarControlFile.Position = progressBarControlFile.Properties.Maximum;
        labelControlFile.Text = string.Format("{0} %", progressBarControlFile.Properties.Maximum);
        Application.DoEvents();
    }
    

    }

    public class CookieAwareWebClient : WebClient{ public CookieContainer CookieContainer { get; set; }

    protected override WebRequest GetWebRequest(Uri address)
    {
        WebRequest request = base.GetWebRequest(address);
        var webRequest = request as HttpWebRequest;
        if (webRequest != null)
        {
            webRequest.CookieContainer = this.CookieContainer;
            webRequest.KeepAlive = false;
        }
        return request;
    }
    

    }}

将 DownloadDataAsync 与 Cookie 感知 Web 客户端结合使用以获取更新进度

  1. 您必须等待 DownloadFileDone 事件。您可以设置一个用于轮询的易失性布尔值,也可以对事件执行此操作。在性能方面只有细微的差异,但通常事件可能是更干净的解决方案(我更喜欢布尔轮询)。在您的情况下,您可能实际上希望等待这种情况在 DocumentAsArray 结束时发生。
  2. http://msdn.microsoft.com/en-us/library/ms144190.aspx 下载的数据在"结果"属性中可用。
  3. 我不知道 DoEvents 方法 - 如果我正确理解您要做什么,您想更新您的 UI?你必须调用InvokeEx(至少这是最简单的,也是我知道的唯一方法)。看看这个伟大的:)文章 http://www.andreas-reiff.de/2011/06/accessing-a-winformwpf-control-from-another-thread-through-invoke/.或者,留在stackoverflow并查看调用任何跨线程代码的最佳方法?。

因此,回顾一下,如果您只想让异步获取进度更新,只需更改 DocumentAsArray 函数以等待 DownloadFileCompleted 事件,如 1 中所述。然后,您所要做的就是注意不要从另一个线程调用UI代码 - 您应该在调试中收到一个异常,告诉您不要这样做(它在发布中运行良好 - 大多数时候)。因此,请使用 InvokeEx-call。