簡體   English   中英

如何在C#中將HttpClient PostAsync()與線程池一起使用?

[英]How to use HttpClient PostAsync() with threadpool in C#?

我正在使用以下代碼將圖像發布到服務器。

var image= Image.FromFile(@"C:\Image.jpg");
Task<string> upload = Upload(image);
upload.Wait();

public static async Task<string> 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<ManualResetEvent>();

    foreach (var image in ImageCollection)
    {
        var resetEvent = new ManualResetEvent(false);
        ThreadPool.QueueUserWorkItem(
            arg =>
            {
                var img = Image.FromFile(image.getPath());
                Task<string> 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM