异步调用 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() 中等待响应,我为每个请求启动一个单独的任务。
如果这是正确的方法,或者我在这里犯了一些重大错误,请告诉我,如果我需要更多细节来解释这个问题。
提前致谢。
你努力实现的是一件好事。不阻塞某些主线程是个好主意,您这样做的方式将会奏效。
但是,如果你这样做,你必须手动控制任务的数量。您可能不希望数字太高,否则过多的并行性可能会影响性能。
.net 中有 classes 有助于通过所谓的线程池管理任务队列。
您使用已知的最大线程数配置线程池,然后将任务排队到池中。线程池 class 负责清空队列并将任务分配给池中的空闲线程。
您可以了解有关线程池的更多信息here on 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..
}
}
}
它api比ThreadPool更好,这样就不用担心线程饥饿
我是基于任务的编程的新手。我必须异步调用 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() 中等待响应,我为每个请求启动一个单独的任务。
如果这是正确的方法,或者我在这里犯了一些重大错误,请告诉我,如果我需要更多细节来解释这个问题。
提前致谢。
你努力实现的是一件好事。不阻塞某些主线程是个好主意,您这样做的方式将会奏效。
但是,如果你这样做,你必须手动控制任务的数量。您可能不希望数字太高,否则过多的并行性可能会影响性能。
.net 中有 classes 有助于通过所谓的线程池管理任务队列。 您使用已知的最大线程数配置线程池,然后将任务排队到池中。线程池 class 负责清空队列并将任务分配给池中的空闲线程。
您可以了解有关线程池的更多信息here on 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..
}
}
}
它api比ThreadPool更好,这样就不用担心线程饥饿