我正在尝试使用服务引用,使用任务调度程序同时发出多个请求。该服务包括返回结果集的同步和异步函数。我有点困惑,我有几个初步问题,然后我会分享我在每个问题上的进展情况。我正在使用一些日志记录、并发可视化工具和 fiddler 来进行调查。最终我想使用响应式(Reactive)调度程序来发出尽可能多的请求。
1) 我应该使用异步函数来发出所有请求吗?
2) 如果我要在多个任务中使用同步函数,那么可能会耗尽我的线程数的有限资源是什么?
这是我目前所拥有的:
var myScheduler = new myScheduler();
var myFactory = new Factory(myScheduler);
var myClientProxy = new ClientProxy();
var tasks = new List<Task<Response>>();
foreach( var request in Requests )
{
var localrequest = request;
tasks.Add( myFactory.StartNew( () =>
{
// log stuff
return client.GetResponsesAsync( localTransaction.Request );
// log some more stuff
}).Unwrap() );
}
Task.WaitAll( tasks.ToArray() );
// process all the requests after they are done
这会运行,但根据 fiddler 的说法,它只是尝试一次完成所有请求。它可能是调度程序,但我相信它比我做的更多。
我还尝试在不使用 unwrap 命令的情况下实现它,而是使用 async await delegate 来实现它,它做了同样的事情。我也尝试过引用 .result 并且这似乎是按顺序进行的。将非同步服务函数调用与调度程序/工厂一起使用,每个客户端最多只能同时获得大约 20 个并发请求。
最佳答案
- 是的。它将允许您的应用程序通过使用更少的线程来完成更多的工作来更好地扩展。
- 线程。当您启动本质上是异步的同步操作(例如
I/O
)时,您有一个阻塞的线程等待操作完成。但是,您可以同时使用此线程来执行 CPU 密集型操作。
限制并发请求量的最简单方法是使用 SemaphoreSlim
这允许 asynchronously wait输入:
async Task ConsumeService()
{
var client = new ClientProxy();
var semaphore = new SemaphoreSlim(100);
var tasks = Requests.Select(async request =>
{
await semaphore.WaitAsync();
try
{
return await client.GetResponsesAsync(request);
}
finally
{
semaphore.Release();
}
}).ToList();
await Task.WhenAll(tasks);
// TODO: Process responses...
}
关于c# - 具有 WCF 服务引用异步功能的任务计划程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24873971/