我正在使用以下代码将图像发布到服务器.
var image= Image.FromFile(@"C:\Image.jpg"); Taskupload = Upload(image); upload.Wait(); public static async Task Upload(Image image) { var uriBuilder = new UriBuilder { Host = "somewhere.net", Path = "/path/", Port = 443, Scheme = "https", Query = "process=false" }; using (var client = new HttpClient()) { client.DefaultRequestHeaders.Add("locale", "en_US"); client.DefaultRequestHeaders.Add("country", "US"); var content = ConvertToHttpContent(image); content.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg"); using (var mpcontent = new MultipartFormDataContent("--myFakeDividerText--") { {content, "fakeImage", "myFakeImageName.jpg"} } ) { using ( var message = await client.PostAsync(uriBuilder.Uri, mpcontent)) { var input = await message.Content.ReadAsStringAsync(); return "nothing for now"; } } } }
我想修改此代码以运行多个线程.我之前使用过"ThreadPool.QueueUserWorkItem"并开始修改代码以利用它.
private void UseThreadPool() { int minWorker, minIOC; ThreadPool.GetMinThreads(out minWorker, out minIOC); ThreadPool.SetMinThreads(1, minIOC); int maxWorker, maxIOC; ThreadPool.GetMaxThreads(out maxWorker, out maxIOC); ThreadPool.SetMinThreads(4, maxIOC); var events = new List(); foreach (var image in ImageCollection) { var resetEvent = new ManualResetEvent(false); ThreadPool.QueueUserWorkItem( arg => { var img = Image.FromFile(image.getPath()); Task upload = Upload(img); upload.Wait(); resetEvent.Set(); }); events.Add(resetEvent); if (events.Count <= 0) continue; foreach (ManualResetEvent e in events) e.WaitOne(); } }
问题是由于调用"upload.Wait()",一次只执行一个线程.所以我仍然按顺序执行每个线程.我不清楚如何将PostAsync与线程池一起使用.
如何通过调整上面的代码使用多个线程将图像发布到服务器?HttpClient PostAsync是最好的方法吗?
我想修改此代码以运行多个线程.
为什么?线程池应仅用于CPU绑定工作(当然还有I/O完成).
您可以通过以下方式完成并发async
:
var tasks = ImageCollection.Select(image => { var img = Image.FromFile(image.getPath()); return Upload(img); }); await Task.WhenAll(tasks);
请注意,我删除了你的Wait
.你应该避免使用Wait
或Result
使用async
任务; 使用await
来代替.是的,这将导致async
您通过代码增长,并且您应该使用async
"一路".