H.W*_*per 4 c# asp.net asynchronous
我正在使用Asp .Net 4.5.1.我有运行任务,调用Web服务,有些可能会失败.我需要运行N个成功的任务,这些任务执行一些轻微的CPU工作,主要是调用Web服务,然后停止,我想要限制.
例如,假设我们在某个集合中有300个URL.我们需要运行一个调用Task<bool> CheckUrlAsync(url)每个函数的函数,带有限制,这意味着,例如,"同时"只运行5次(换句话说,在任何给定时间最多使用5个连接).此外,我们只想执行N(假设100)成功操作,然后停止.
你会怎么做?
使用Semaphore slim.
var semaphore = new SemaphoreSlim(5);
var tasks = urlCollection.Select(async url =>
{
await semaphore.WaitAsync();
try
{
return await CheckUrlAsync(url);
}
finally
{
semaphore.Release();
}
};
while(tasks.Where(t => t.Completed).Count() < 100)
{
await.Task.WhenAny(tasks);
}
Run Code Online (Sandbox Code Playgroud)
虽然我更喜欢使用Rx.Net来生成更好的代码.
using(var semaphore = new SemaphoreSlim(5))
{
var results = urlCollection.ToObservable()
.Select(async url =>
{
await semaphore.WaitAsync();
try
{
return await CheckUrlAsync(url);
}
finally
{
semaphore.Release();
}
}).Take(100).ToList();
}
Run Code Online (Sandbox Code Playgroud)
好的......这会很有趣.
public static class SemaphoreHelper
{
public static Task<T> ContinueWith<T>(
this SemaphoreSlim semaphore,
Func<Task<T>> action)
var ret = semaphore.WaitAsync()
.ContinueWith(action);
ret.ContinueWith(_ => semaphore.Release(), TaskContinuationOptions.None);
return ret;
}
var semaphore = new SemaphoreSlim(5);
var results = urlCollection.Select(
url => semaphore.ContinueWith(() => CheckUrlAsync(url)).ToList();
Run Code Online (Sandbox Code Playgroud)
我确实需要补充一点,现在的代码仍将运行所有300个URL,它只会更快地返回......这就是全部.您需要将取消令牌添加semaphore.WaitAsync(token)到取消排队的工作.我再次建议使用Rx.Net.它更容易使用Rx.Net来获取取消令牌.Take(100).
| 归档时间: |
|
| 查看次数: |
1290 次 |
| 最近记录: |