获取异步调用的进度

时间:2014-03-24 22:59:35

标签: c# .net asynchronous webclient imgur

我使用从博客中获取的代码块,使用API​​ v3将图像上传到IMGur。

它工作正常,但我想实现一个进度条系统,让用户知道已经上传了多少,如果该程序处理高分辨率图像。

到目前为止,我还没有能够这样做。

我不是一位经验丰富的程序员,只是将其作为一个学习项目。

守则:

public object UploadImage(string image) 
{ 
    WebClient w = new WebClient();
    w.UploadProgressChanged += (s, e) => { };
    w.UploadValuesCompleted += (s, e) => { };
    w.Headers.Add("Authorization", "Client-ID " + ClientId);
    System.Collections.Specialized.NameValueCollection Keys = new System.Collections.Specialized.NameValueCollection(); 
    try 
    { 
        Keys.Add("image", Convert.ToBase64String(File.ReadAllBytes(image))); 
        byte[] responseArray = w.UploadValues("https://api.imgur.com/3/image", Keys);


        dynamic result = Encoding.ASCII.GetString(responseArray); System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("link\":\"(.*?)\""); 
        System.Text.RegularExpressions.Match match = reg.Match(result); 
        string url = match.ToString().Replace("link\":\"", "").Replace("\"", "").Replace("\\/", "/");
        textBox1.Text = url;
        return url; 
    }
    catch (Exception s) 
    { 
        MessageBox.Show("Something went wrong. " + s.Message); 
            return "Failed!"; 
    } 
}

起初我尝试使用事件UploadProgressChangedUploadValuesCompleted,但是没有触发它们,我的理论是它们在调用UploadValuesAsync而不是UploadValues时被触发。

  1. 如何实施进度系统?
  2. 异步和普通转移有什么区别?

1 个答案:

答案 0 :(得分:2)

异步和正常传输之间的区别在于,UploadValues方法将阻止当前线程,直到所有数据都已传输完毕。由于线程在此时被阻止,因此您也无法捕获任何事件。因此,您必须使用异步方法UploadValuesAsync,它将在后台传输数据,并且您可以继续执行代码。
UploadProgressChanged只会触发UploadValuesAsync。您的代码应如下所示(未测试!):

public String UploadImage(string image) 
    { 
        WebClient w = new WebClient();

        w.UploadProgressChanged += (s, e) =>
        {
            myProgressBar.Maximum = (int)e.TotalBytesToSend;
            myProgressBar.Value = (int)e.BytesSent;
        };

        w.UploadValuesCompleted += new UploadValuesCompletedEventHandler(UploadComplete);

        w.Headers.Add("Authorization", "Client-ID " + ClientId);
        System.Collections.Specialized.NameValueCollection Keys = new System.Collections.Specialized.NameValueCollection(); 
        try 
        { 
            Keys.Add("image", Convert.ToBase64String(File.ReadAllBytes(image))); 
            w.UploadValuesAsync("https://api.imgur.com/3/image", Keys);

            return "Uploading..";
        } catch (Exception s) 
        { 
            MessageBox.Show("Something went wrong. " + s.Message); 
                return "Failed!"; 
        } 
    }

public void UploadComplete(Object sender, UploadValuesCompletedEventArgs e)
{
    myProgressBar.Value = 100;

    byte[] responseArray = e.Result;
    dynamic result = Encoding.ASCII.GetString(responseArray); 
    System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("link\":\"(.*?)\""); 
    System.Text.RegularExpressions.Match match = reg.Match(result); 
    string url = match.ToString().Replace("link\":\"", "").Replace("\"", "").Replace("\\/", "/");
    textBox1.Text = url;
}

修改
我在UploadValuesAsync调用后将代码移到了w.UploadValuesCompleted。您可以在Result类的UploadValuesCompletedEventArgs字段中找到服务器响应,该字段将传递给变量e中的事件。
您的方法UploadImage现在将在进度开始时返回上传,并且您必须在w.UploadValuesCompleted事件中进行休息。