简体   繁体   English

如果文件超过500mb,DownloadFileAsync应用程序没有响应?

[英]DownloadFileAsync application not responding if file is over 500mb?

so I'm using webClient.DownloadFileAsync(url, sFilePathToWriteFileTo); 所以我正在使用webClient.DownloadFileAsync(url, sFilePathToWriteFileTo); to download a file 下载文件

Url is string url = "http://localhost/1.zip"; 网址是string url = "http://localhost/1.zip";

sFilePathToWriteFileTo is root directory sFilePathToWriteFileTo是根目录

Whenever I download the 500mb zip archive, my label1 goes berserk and says "Downloading with INF kb/s" and that's about when it starts not responding and crashes 每当我下载500mb的zip存档时,我的label1就会发疯,并说“以INF kb / s下载”,这就是它开始不响应并崩溃的原因

label1 is label1.Text = string.Format("Downloading with {0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00")); label1是label1.Text = string.Format("Downloading with {0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00"));

It works perfectly fine when I'm downloading low size files, 20mb-50mb 当我下载20mb-50mb的小文件时,它工作得很好

Oh btw, (I just re-read my post), sw is StopWatch, incase you wonder 哦,顺便说一句,(我只是重新阅读我的帖子),sw是StopWatch,以防万一您想知道

What is the problem here, and how can I solve it? 这是什么问题,我该如何解决?

-- Edit, added webClient: -编辑,添加了webClient:

using (webClient = new WebClient())
                {
                    webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(wzCompleted);
                    webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wzProgressChanged);
                    Uri url = new Uri(sUrlToReadFileFrom);
                    sw.Start();
                    try
                    {
                        webClient.DownloadFileAsync(url, sFilePathToWriteFileTo);
                    }
                    catch (Exception ex)
                    {
                        downloadInfo.Text = ex.Message;
                    }
                }

wzProgressChanged: wzProgressChanged:

private void wzProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        statusContent.Text = "Downloading new game files";
        downloadInfo.Text = "Downloading: " + string.Format("{0} MB / {1} MB", (e.BytesReceived / 1024d / 1024d).ToString("0.00"), (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00")) + " with " + string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00")) + " (" + e.ProgressPercentage.ToString() + "%" + ")";
        progressBar1.Value = e.ProgressPercentage;
    }

wzCompleted: It's just enabling 2 buttons and disabling 2 others, no need for this? wzCompleted:只是启用2个按钮并禁用2个其他按钮,不需要吗?

Do 3 things in your wzProgressChanged handler: wzProgressChanged处理程序中执行3件事:

  1. Make sure you marshal the control updates onto the UI thread (assuming it's WinForms use InvokeRequired and Invoke ) 确保将控件更新编组到UI线程上(假设它是WinForms使用InvokeRequiredInvoke
  2. Make sure sw.Elapsed.TotalSeconds isn't zero to avoid divide by zero 确保sw.Elapsed.TotalSeconds不为零,以避免被零除
  3. Wrap the whole body of the handler in a try catch so you can see exceptions your code may be throwing. 将处理程序的整个内容包装在try catch中,这样您就可以看到代码可能抛出的异常。

Read the documentation about InvokeRequired. 阅读有关InvokeRequired的文档。 It will tell you all about the UI thread and how to make sure you are updating the UI appropriately. 它将告诉您有关UI线程的所有信息以及如何确保适当地更新UI。 I would make the code look something like this (not tested or even compiled but is pretty close) 我会让代码看起来像这样(未经测试甚至编译,但是非常接近)

private void wzProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    if (this.InvokeRequired)
    {
        this.Invoke(() => wzProgressChanged(sender, e));
    }
    else if (sw.Elapsed.TotalSeconds > 0)
    {
        try
        {
            statusContent.Text = "Downloading new game files";
            downloadInfo.Text = "Downloading: " + string.Format("{0} MB / {1} MB", (e.BytesReceived / 1024d / 1024d).ToString("0.00"), (e.TotalBytesToReceive / 1024d / 1024d).ToString("0.00")) + " with " + string.Format("{0} kb/s", (e.BytesReceived / 1024d / sw.Elapsed.TotalSeconds).ToString("0.00")) + " (" + e.ProgressPercentage.ToString() + "%" + ")";
            progressBar1.Value = e.ProgressPercentage;
        }
        catch(Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.Message);
        }
    }
}

In addition to what dkackman suggested, I'd also suggest being a bit more selective about how often you update your label and maybe put some additional checking around your values to ensure you don't get values line NaN/INF. 除了dkackman提出的建议之外,我还建议您对标签的更新频率有更多的选择,并可能对值进行一些额外的检查,以确保您不会在NaN / INF中得到值。 See other posts here on SO around what they mean exactly. 请参阅此处的其他帖子 ,了解它们的确切含义。 Look at methods like Double.IsInfinity to help you determine if your calc resulted in a number that can be displayed or not. 查看类似Double.IsInfinity的方法,以帮助您确定您的计算是否导致可以显示的数字。

Also, do some of your calculations outside of your string format statement and based on your findings, you could decide what information to provide to the user. 另外,在字符串格式语句之外进行一些计算,并根据发现,可以确定要提供给用户的信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM