C#内置HttpClient发Multipart请求上传时以及等待服务器处理完上传的下载中,进度怎知?
本帖最后由 ilovecomputer66 于 2023-1-20 18:47 编辑是这样的,调用第三方平台的API,上传一个本地图片(会很大,几十MB,然后他们服务器处理后,返回下载处理后的图片)
想知道上传的进度(即已经上传多少MB),服务器处理完后,response返回处理后的文件时,也要知道下载进度
看网上有些例子,是还需要再添加包Microsoft.AspNet.WebApi.Client ,比如:https://blog.csdn.net/adai3846250/article/details/117159419
但我按它这个做,直接程序无法运行,会卡死,但不报错,不知道什么原因(下面button2的点击事件),如果不用文中说的ProgressMessageHandler,不监控进度,即button1我原来写的点击事件,就没问题
(我即便把ProgressMessageHandler_HttpSendProgress 2个函数,里面清空掉),还是会让整个程序卡死,不知道为什么
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void SafeInvoke(Action action)
{
if (this.IsDisposed == false && this.Created == true)
{
this.Invoke(action);
}
}
private void button1_Click(object sender, EventArgs e)
{
HttpClientHandler handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
handler.CheckCertificateRevocationList = false;
handler.UseCookies = false;
HttpClient httpClient = new HttpClient(handler);
httpClient.Timeout = TimeSpan.FromMilliseconds(50000);
MultipartFormDataContent formData = new MultipartFormDataContent();
formData.Headers.Add("X-Api-Key", "hdNWthxGKPjxYMxwY1riGvBN"); // hdNWthxGKPjxYMxwY1riGvBN
formData.Add(new ByteArrayContent(File.ReadAllBytes(@"C:\Users\zhang\Desktop\input2.jpg")), "image_file", "input1.jpg");
formData.Add(new StringContent("auto"), "size");
var response = httpClient.PostAsync("https://api.remove.bg/v1.0/removebg", formData).Result;
if (response.IsSuccessStatusCode)
{
FileStream fileStream = new FileStream(@"C:\Users\zhang\Desktop\temp3.jpg", FileMode.Create, FileAccess.Write, FileShare.None);
response.Content.CopyToAsync(fileStream).ContinueWith((copyTask) => { fileStream.Close(); });
MessageBox.Show("ok");
}
else
{
MessageBox.Show("Error: " + response.Content.ReadAsStringAsync().Result);
}
}
private void button2_Click(object sender, EventArgs e)
{
HttpClientHandler handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
handler.CheckCertificateRevocationList = false;
handler.UseCookies = false;
ProgressMessageHandler progressMessageHandler = new ProgressMessageHandler(handler);
progressMessageHandler.HttpSendProgress += ProgressMessageHandler_HttpSendProgress;
progressMessageHandler.HttpReceiveProgress += ProgressMessageHandler_HttpReceiveProgress;
HttpClient httpClient = new HttpClient(progressMessageHandler);
httpClient.Timeout = TimeSpan.FromMilliseconds(50000);
MultipartFormDataContent formData = new MultipartFormDataContent();
formData.Headers.Add("X-Api-Key", "hdNWthxGKPjxYMxwY1riGvBN"); // hdNWthxGKPjxYMxwY1riGvBN
formData.Add(new ByteArrayContent(File.ReadAllBytes(@"C:\Users\zhang\Desktop\input3.jpg")), "image_file", "input1.jpg");
formData.Add(new StringContent("auto"), "size");
var response = httpClient.PostAsync("https://api.remove.bg/v1.0/removebg", formData).Result;
if (response.IsSuccessStatusCode)
{
FileStream fileStream = new FileStream(@"C:\Users\zhang\Desktop\temp3.jpg", FileMode.Create, FileAccess.Write, FileShare.None);
response.Content.CopyToAsync(fileStream).ContinueWith((copyTask) => { fileStream.Close(); });
MessageBox.Show("ok");
}
else
{
MessageBox.Show("Error: " + response.Content.ReadAsStringAsync().Result);
}
}
private void ProgressMessageHandler_HttpSendProgress(object sender, HttpProgressEventArgs e)
{
this.SafeInvoke(() =>
{
LblUpload.Text = e.ProgressPercentage + "%";
this.Refresh();
});
}
private void ProgressMessageHandler_HttpReceiveProgress(object sender, HttpProgressEventArgs e)
{
this.SafeInvoke(() =>
{
LblDownload.Text = e.ProgressPercentage + "%";
this.Refresh();
});
}
} var response = httpClient.PostAsync("https://api.remove.bg/v1.0/removebg", formData).Result;
你这把异步转成同步了,换异步试试 ie81com 发表于 2023-1-18 11:34
var response = httpClient.PostAsync("https://api.remove.bg/v1.0/removebg", formData).Result;
你这 ...
我知道,但我说的卡死是程序彻底完蛋,永远执行不下去。目前试的图不大,应该几秒就完。但button2写法永远卡死,button1就瞬间完成 ie81com 发表于 2023-1-18 11:34
var response = httpClient.PostAsync("https://api.remove.bg/v1.0/removebg", formData).Result;
你这 ...
也可能是我理解不对,兄弟按你想的,改一下我代码,我看下你具体想表达什么意思么 ilovecomputer66 发表于 2023-1-18 11:46
也可能是我理解不对,兄弟按你想的,改一下我代码,我看下你具体想表达什么意思么
以下代码测试通过
using System.Net.Http.Handlers;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void SafeInvoke(Action action)
{
if (this.IsDisposed == false && this.Created == true)
{
this.Invoke(action);
}
}
private void button1_Click(object sender, EventArgs e)
{
HttpClientHandler handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
handler.CheckCertificateRevocationList = false;
handler.UseCookies = false;
HttpClient httpClient = new HttpClient(handler);
httpClient.Timeout = TimeSpan.FromMilliseconds(50000);
MultipartFormDataContent formData = new MultipartFormDataContent();
formData.Headers.Add("X-Api-Key", "hdNWthxGKPjxYMxwY1riGvBN"); // hdNWthxGKPjxYMxwY1riGvBN
formData.Add(new ByteArrayContent(File.ReadAllBytes(@"d:\test.jpg")), "image_file", "test.jpg");
formData.Add(new StringContent("auto"), "size");
var response = httpClient.PostAsync("https://api.remove.bg/v1.0/removebg", formData).Result;
if (response.IsSuccessStatusCode)
{
FileStream fileStream = new FileStream(@"d:\test.png", FileMode.Create, FileAccess.Write, FileShare.None);
response.Content.CopyToAsync(fileStream).ContinueWith((copyTask) => { fileStream.Close(); });
MessageBox.Show("ok");
}
else
{
MessageBox.Show("Error: " + response.Content.ReadAsStringAsync().Result);
}
}
private async void button2_Click(object sender, EventArgs e)
{
HttpClientHandler handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
handler.CheckCertificateRevocationList = false;
handler.UseCookies = false;
ProgressMessageHandler progressMessageHandler = new ProgressMessageHandler(handler);
progressMessageHandler.HttpSendProgress += ProgressMessageHandler_HttpSendProgress;
progressMessageHandler.HttpReceiveProgress += ProgressMessageHandler_HttpReceiveProgress;
HttpClient httpClient = new HttpClient(progressMessageHandler);
httpClient.Timeout = TimeSpan.FromMilliseconds(50000);
MultipartFormDataContent formData = new MultipartFormDataContent();
formData.Headers.Add("X-Api-Key", "hdNWthxGKPjxYMxwY1riGvBN"); // hdNWthxGKPjxYMxwY1riGvBN
formData.Add(new ByteArrayContent(File.ReadAllBytes(@"d:\test.jpg")), "image_file", "test.jpg");
formData.Add(new StringContent("auto"), "size");
var response = await httpClient.PostAsync("https://api.remove.bg/v1.0/removebg", formData);
if (response.IsSuccessStatusCode)
{
FileStream fileStream = new FileStream(@"d:\test.png", FileMode.Create, FileAccess.Write, FileShare.None);
await response.Content.CopyToAsync(fileStream).ContinueWith((copyTask) => { fileStream.Close(); });
MessageBox.Show("ok");
}
else
{
MessageBox.Show("Error: " + response.Content.ReadAsStringAsync().Result);
}
}
private void ProgressMessageHandler_HttpSendProgress(object? sender, HttpProgressEventArgs e)
{
this.SafeInvoke(() =>
{
LblUpload.Text = e.ProgressPercentage + "%";
this.Refresh();
});
}
private void ProgressMessageHandler_HttpReceiveProgress(object? sender, HttpProgressEventArgs e)
{
this.SafeInvoke(() =>
{
LblDownload.Text = e.ProgressPercentage + "%";
this.Refresh();
});
}
}
} ie81com 发表于 2023-1-18 12:12
以下代码测试通过
using System.Net.Http.Handlers;
非常感谢。但是,发现上传进度不太对
把回调函数改为打印,结果如下
上传:0%
上传:0%
上传:99%
上传:99%
上传:99%
上传:100%
这是什么原因,按理说上传10MB的,不应该这样。
而下载的处理后的图片更小。却能清晰体现进度
下载:1%
下载:5%
下载:6%
下载:7%
下载:8%
下载:9%
下载:9%
下载:11%
下载:12%
下载:12%
下载:13%
下载:14%
下载:15%
下载:16%
下载:17%
下载:18%
下载:19%
下载:21%
下载:21%
下载:22%
下载:23%
下载:24%
下载:25%
下载:26%
下载:27%
下载:28%
下载:29%
下载:30%
下载:31%
下载:32%
下载:33%
下载:34%
下载:35%
下载:36%
下载:37%
下载:38%
下载:39%
下载:39%
下载:40%
下载:41%
下载:42%
下载:42%
下载:42%
下载:43%
下载:44%
下载:45%
下载:46%
下载:47%
下载:48%
下载:49%
下载:50%
下载:51%
下载:52%
下载:53%
下载:53%
下载:54%
下载:55%
下载:56%
下载:57%
下载:58%
下载:59%
下载:60%
下载:61%
下载:62%
下载:63%
下载:64%
下载:64%
下载:64%
下载:65%
下载:66%
下载:67%
下载:68%
下载:69%
下载:70%
下载:71%
下载:72%
下载:73%
下载:74%
下载:74%
下载:75%
下载:76%
下载:77%
下载:78%
下载:79%
下载:80%
下载:81%
下载:82%
下载:83%
下载:84%
下载:85%
下载:85%
下载:86%
下载:87%
下载:88%
下载:89%
下载:90%
下载:91%
下载:92%
下载:93%
下载:94%
下载:95%
下载:95%
下载:96%
下载:97%
下载:98%
下载:99%
下载:100% 这个貌似是服务器问题吧,没有实时返回进度 ilovecomputer66 发表于 2023-1-18 15:18
非常感谢。但是,发现上传进度不太对
把回调函数改为打印,结果如下
搜到一篇,供你参考。。
//zhuanlan.zhihu.com/p/23757396 感谢 ie81com
ie81com 发表于 2023-1-18 16:37
搜到一篇,供你参考。。
//zhuanlan.zhihu.com/p/23757396
@ie81com
我找到了个解决方案,上传速度也可以很精确http://cn.voidcc.com/question/p-yzihfdcl-hs.html
但还想请教下兄弟,就之前我那个同步的写法,究竟为什么如果用到ProgressMessageHandler,就会卡死呢?如果请求不是异步执行的,为什么又对ProgressMessageHandler产生影响,进而导致整个程序永远卡死呢
页:
[1]
2