获取异步调用的进度

本文关键字:调用 异步 获取 | 更新日期: 2023-09-27 17:53:21

我正在使用从博客中获得的代码块,使用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. 异步传输和正常传输的区别是什么?

获取异步调用的进度

aync和普通传输的区别在于,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中。您可以在UploadValuesCompletedEventArgs类的Result字段中找到服务器响应,该字段传递给变量e中的事件。
当进度开始时,您的方法UploadImage现在将返回上传,您将不得不在w.UploadValuesCompleted事件中完成您的其余工作。