c# - 在c#中显示下载进度

标签 c# .net

我创建了这个程序,它向 twitter 发送 html 请求并将推文下载到数据库中。该程序位于控制台中,并使用 c# 进行编码。我不确定显示用户信息的下载进度。

示例:我正在为用户 alice 下载屏幕名称、位置等并将其写入数据库

问题:我怎样才能向用户显示完成 10% 之类的进度。

我的网络请求代码(小例子)如下:

WebClient wc = new WebClient();
string url = "https://api.twitter.com/1/users/lookup.json?screen_name=" +username;      

最佳答案

恰好我写了一个WebClient的自定义子类,可以显示更新进度。它每 1MB 引发一个事件(因为那是我的需要,请参阅 NotifyMegabyteIncrement)但可以轻松修改。

public class MyWebClient : WebClient, IDisposable
{
    public int Timeout { get; set; }
    public int TimeUntilFirstByte { get; set; }
    public int TimeBetweenProgressChanges { get; set; }

    public long PreviousBytesReceived { get; private set; }
    public long BytesNotNotified { get; private set; }

    public string Error { get; private set; }
    public bool HasError { get { return Error != null; } }

    private bool firstByteReceived = false;
    private bool success = true;
    private bool cancelDueToError = false;

    private EventWaitHandle asyncWait = new ManualResetEvent(false);
    private Timer abortTimer = null;

    const long ONE_MB = 1024 * 1024;

    public delegate void PerMbHandler(long totalMb);

    public event PerMbHandler NotifyMegabyteIncrement;

    public MyWebClient(int timeout = 60000, int timeUntilFirstByte = 30000, int timeBetweenProgressChanges = 15000)
    {
        this.Timeout = timeout;
        this.TimeUntilFirstByte = timeUntilFirstByte;
        this.TimeBetweenProgressChanges = timeBetweenProgressChanges;

        this.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(MyWebClient_DownloadFileCompleted);
        this.DownloadProgressChanged += new DownloadProgressChangedEventHandler(MyWebClient_DownloadProgressChanged);

        abortTimer = new Timer(AbortDownload, null, TimeUntilFirstByte, System.Threading.Timeout.Infinite);
    }

    protected void OnNotifyMegabyteIncrement(long totalMb)
    {
        if (NotifyMegabyteIncrement != null) NotifyMegabyteIncrement(totalMb);
    }

    void AbortDownload(object state)
    {
        cancelDueToError = true;
        this.CancelAsync();
        success = false;
        Error = firstByteReceived ? "Download aborted due to >" + TimeBetweenProgressChanges + "ms between progress change updates." : "No data was received in " + TimeUntilFirstByte + "ms";
        asyncWait.Set();
    }

    void MyWebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        if (cancelDueToError) return;

        long additionalBytesReceived = e.BytesReceived - PreviousBytesReceived;
        PreviousBytesReceived = e.BytesReceived;
        BytesNotNotified += additionalBytesReceived;

        if (BytesNotNotified > ONE_MB)
        {
            OnNotifyMegabyteIncrement(e.BytesReceived);
            BytesNotNotified = 0;
        }
        firstByteReceived = true;
        abortTimer.Change(TimeBetweenProgressChanges, System.Threading.Timeout.Infinite);
    }

    public bool DownloadFileWithEvents(string url, string outputPath)
    {
        asyncWait.Reset();
        Uri uri = new Uri(url);
        this.DownloadFileAsync(uri, outputPath);
        asyncWait.WaitOne();

        return success;
    }

    void MyWebClient_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
    {
        if (cancelDueToError) return;
        asyncWait.Set();
    }

    protected override WebRequest GetWebRequest(Uri address)
    {            
        var result = base.GetWebRequest(address);
        result.Timeout = this.Timeout;
        return result;
    }

    void IDisposable.Dispose()
    {
        if (asyncWait != null) asyncWait.Dispose();
        if (abortTimer != null) abortTimer.Dispose();

        base.Dispose();
    }
}

关于c# - 在c#中显示下载进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11509041/

相关文章:

c# - 每个命名空间分支的理想类数

c# - 比较两个列表的差异

c# - 获取字符串的编码

c# - 无法在已部署的 matlab dll 中使用 .NET 方法

c# - 从具体化 'System.Guid' 类型到 'System.String' 类型的指定转换无效

c# - 如何从 Process.start() 获取 processID

c# - 如何从数据绑定(bind)组合框中隐藏所选项目(Datagridviewcombobox)

.net - Windows 应用程序已停止工作::事件名称 CLR20r3

c# - 如何处理 SqlException

c# - 如何将 SVG 文件转换为 WMF 格式?