簡體   English   中英

異步調用 WCF 服務並在新任務中等待它

[英]Call a WCF service Asynchronously and Wait for it in a New Task

我是基於任務的編程的新手。 我必須異步調用 WCF 服務並啟動一個任務來等待它,因為我不想在相同的方法中等待,所以我編寫了類似這樣的代碼

void MyMainMethod()
{
   for(int j=0;j<10; j++)
   {

      int I = 100;
      Task<response> res =  _client.GetValueAsnc(request);

       //Do some work

       Task.Run(()=> WaitForResponse(res , I));
    }
}

Async Task WaitForResponse(Task<response> res , int I)
{
   await res;

   if(res.responsecode == "Success")
   {
      //udatateDB...
   }
 
   else
   {
      //update DB with Error Message..
   }
}

這樣,如果我在循環中調用此服務 10 次,它將啟動 10 個任務並給我響應,而不是在 MyMainMethod() 中等待響應,我將為每個請求啟動一個單獨的任務。

請讓我知道這是否是正確的方法,或者我在這里犯了一些重大錯誤,並且如果我需要更多細節來解釋這個問題。

提前致謝。

你試圖達到的目標是一件好事。 不阻塞某些主線程是個好主意,而且你這樣做的方式會奏效。

但是,如果這樣做,則必須手動控制任務的數量。 您可能不希望 go 的數量太高,否則過多的並行性可能會損害性能。

.net 中有一些類可以幫助通過所謂的線程池管理任務隊列。 您使用已知的最大線程數配置線程池,然后將任務排隊到池中。 線程池 class 負責清空隊列並將任務分配給池中的空閑線程。

您可以在 ms docs 上了解有關線程池的更多信息

下面的示例來自 MS 文檔站點。

using System;
using System.Threading;

public class Example 
{
    public static void Main() 
    {
        // Queue the task.
        ThreadPool.QueueUserWorkItem(ThreadProc);
        Console.WriteLine("Main thread does some work, then sleeps.");
        Thread.Sleep(1000);

        Console.WriteLine("Main thread exits.");
    }

    // This thread procedure performs the task.
    static void ThreadProc(Object stateInfo) 
    {
        // No state object was passed to QueueUserWorkItem, so stateInfo is null.
        Console.WriteLine("Hello from the thread pool.");
    }
}
// The example displays output like the following:
//       Main thread does some work, then sleeps.
//       Hello from the thread pool.
//       Main thread exits.

為什么不在線程池上使用任務並行庫。

class Client
{
    internal async Task<string> GetValueAsnc()
    {
        Console.WriteLine("GetValueAsync");
        await Task.Delay(TimeSpan.FromSeconds(2));
        return "success";
    }
}
class Program
{
    private static readonly Client _client = new Client();

    static void Main(string[] args)
    {
        var tasks = new List<Task>();
        for (int j = 0; j < 10; j++)
        {
            tasks.Add(WaitForResponse());
        }

        Task.WhenAll(tasks);
        Console.WriteLine("Tasks finished");
        Console.ReadLine();
    }

    static async Task WaitForResponse()
    {
        var res = await _client.GetValueAsnc();

        if (res == "Success")
        {
            //udatateDB...
        }

        else
        {
            //update DB with Error Message..
        }
    }
}

它比 ThreadPool 有更好的 api,這樣不用擔心線程飢餓

暫無
暫無

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

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