2012-07-16 57 views
2

我創建了這個程序,它發送一個html請求到twitter並下載到數據庫中。該程序在控制檯中,並使用c#編碼。我不確定顯示用戶信息的下載進度。在c中顯示下載進度#

例子:我下載屏幕名,位置等用戶愛麗絲和我寫入數據庫

問:我如何可以顯示用戶完成進度爲10%,類似的東西。

我對web請求(例如小)的代碼如下:

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

回答

10

它碰巧的是,我寫了Web客戶端,可以顯示更新進度的自定義子類。它每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(); 
    } 
} 
+0

謝謝你,會嘗試:) – Phantom 2012-07-17 15:33:33

+0

這篇對你的工作? – 2013-04-17 15:31:25

3
private WebClient mWebClient = new WebClient(); 
//... 
mWebClient.DownloadProgressChanged += (sender, e) => progressPercentageChanged(e.ProgressPercentage); //your method to display the percentage 
mWebClient.DownloadFileCompleted += (sender, e) => yourMethodToProcessTheFile(); 
mWebClient.DownloadFileAsync(uri, fileNameOnDisk); 
//you need to keep the instance of webclient, so it does not get garbage collected 
+0

謝謝你的幫助:D – Phantom 2012-07-17 15:33:59