【问题标题】:Get progress of an async call获取异步调用的进度
【发布时间】:2014-05-02 13:45:16
【问题描述】:

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

【问题讨论】:

    标签: c# .net asynchronous webclient imgur


    【解决方案1】:

    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 现在将在进度开始时返回Uploading,您必须在w.UploadValuesCompleted 事件中完成剩余工作。

    【讨论】:

    • UploadValuesAsync 返回 void 而 UploadValues 返回一个字节数组,有什么建议吗?
    • 您可能需要在UploadValuesCompleated 事件处理程序中移动UploadValuesAsync 调用之后的代码并从e.Result 读取结果。我一回到家就会更新我的答案。
    • 好的,我现在更新了我的代码,还没有经过测试。让我知道这是否有效
    • 非常感谢!您的代码不起作用,但它确实为我指明了正确的方向,谢谢!, e.Result() 返回一个 byte[] 而不是字符串,所以我将它放入旧的 responseArray bytearray 并且它完美地工作。我想为其他人注意的一点,e.ProgressPercentage 不起作用;我用了 myProgressBar.Maximum = (int)e.TotalBytesToSend; myProgressBar.Value = (int)e.BytesSent;
    • 顺便说一句,为了代码效率和易于阅读,是使用 lambda 表达式还是使用普通的类方法结构更好?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    相关资源
    最近更新 更多