C# 管理对共享资源的并发异步调用
我的应用程序中有一组自定义对象,每个对象都可以通过调用某个异步方法来更新自身,该方法基本上扫描网页以截获网页上的更新数据,并将其存储在sqlite数据库中 或者至少他们在不久的将来能够自动更新(事情已经在“手动”模式下运行),因为同时需要更新的对象可能有数百个C# 管理对共享资源的并发异步调用,c#,multithreading,C#,Multithreading,我的应用程序中有一组自定义对象,每个对象都可以通过调用某个异步方法来更新自身,该方法基本上扫描网页以截获网页上的更新数据,并将其存储在sqlite数据库中 或者至少他们在不久的将来能够自动更新(事情已经在“手动”模式下运行),因为同时需要更新的对象可能有数百个 我曾考虑过一些“控制中心”类对超过一定数量的允许并发调用(比如3个)的调用进行查询,但我不知道从哪里开始。那么,有人能给我指出任何工作示例(甚至是模板,都可以!)来开始学习吗?我会从谷歌搜索“并发异步队列c”开始。在其他问题中,有一个非常
我曾考虑过一些“控制中心”类对超过一定数量的允许并发调用(比如3个)的调用进行查询,但我不知道从哪里开始。那么,有人能给我指出任何工作示例(甚至是模板,都可以!)来开始学习吗?我会从谷歌搜索“并发异步队列c”开始。在其他问题中,有一个非常重要的问题。虽然它不是并发的,但是您可以使用三个队列,也可以从问题中修改队列。您还可以按照这个问题答案中的建议,尝试使用来实现它。使用异步和等待模式管理并发相当简单,有很多方法可以做到这一点。我用
semaphorsim
、ActionBlock
和反应式扩展为您提供了世界上最精心设计的示例
给定一些随机异步IO工作负载
public static async Task<PingReply> SomethingAsync(IPAddress address)
{
try
{
Interlocked.Increment(ref _counter);
var ping = new Ping();
var result = await ping.SendPingAsync(address, 1000);
Console.WriteLine($"{Interlocked.Read(ref _counter)} : {address} - {result.Status} {result.RoundtripTime}ms");
return result;
}
catch (PingException ex)
{
Console.WriteLine($"{Interlocked.Read(ref _counter)} : {address} - {ex.Message}");
}
finally
{
Interlocked.Decrement(ref _counter);
}
return null;
}
输出
3 : 66.65.213.229 - TimedOut 0ms
3 : 26.99.52.159 - TimedOut 0ms
3 : 143.134.242.155 - TimedOut 0ms
3 : 110.29.95.203 - DestinationHostUnreachable 0ms
3 : 66.249.81.37 - Success 309ms
3 : 174.59.246.66 - TimedOut 0ms
3 : 163.176.88.190 - TimedOut 0ms
3 : 83.83.27.11 - TimedOut 0ms
3 : 19.156.14.248 - TimedOut 0ms
3 : 228.198.82.154 - TimedOut 0ms
3 : 89.90.185.217 - TimedOut 0ms
1 : 197.101.34.54 - TimedOut 0ms
---------
3 : 143.134.242.155 - TimedOut 0ms
3 : 26.99.52.159 - TimedOut 0ms
3 : 66.65.213.229 - TimedOut 0ms
3 : 110.29.95.203 - DestinationHostUnreachable 0ms
3 : 66.249.81.37 - Success 309ms
3 : 174.59.246.66 - TimedOut 0ms
3 : 83.83.27.11 - TimedOut 0ms
3 : 163.176.88.190 - TimedOut 0ms
3 : 89.90.185.217 - DestinationHostUnreachable 0ms
3 : 228.198.82.154 - TimedOut 0ms
3 : 19.156.14.248 - TimedOut 0ms
3 : 197.101.34.54 - TimedOut 0ms
---------
3 : 66.65.213.229 - TimedOut 0ms
3 : 26.99.52.159 - TimedOut 0ms
1 : 143.134.242.155 - TimedOut 0ms
3 : 110.29.95.203 - DestinationHostUnreachable 0ms
3 : 66.249.81.37 - Success 309ms
3 : 163.176.88.190 - TimedOut 0ms
3 : 174.59.246.66 - TimedOut 0ms
3 : 83.83.27.11 - TimedOut 0ms
3 : 89.90.185.217 - DestinationHostUnreachable 0ms
3 : 228.198.82.154 - TimedOut 0ms
3 : 19.156.14.248 - TimedOut 0ms
3 : 197.101.34.54 - TimedOut 0ms
public static async Task Test2(IEnumerable<IPAddress> list)
{
var block = new ActionBlock<IPAddress>(SomethingAsync,
new ExecutionDataflowBlockOptions()
{
MaxDegreeOfParallelism = 3
});
await Task.WhenAll(list.Select(x => block.SendAsync(x)));
block.Complete();
await block.Completion;
}
public static async Task Test3(IEnumerable<IPAddress> list)
{
await list
.ToObservable()
.Select(x => Observable.FromAsync(() => SomethingAsync(x)))
.Merge(3)
.ToList();
}
// a list of something
var list = Enumerable
.Range(0, 20)
.Select(x => RandomIpAddress())
.ToList();
await Test1(list);
Console.WriteLine("---------");
await Test2(list);
// not included in the Online demo,
// as I was having trouble loading the nuget in .net fiddle
Console.WriteLine("---------");
await Test3(list);
3 : 66.65.213.229 - TimedOut 0ms
3 : 26.99.52.159 - TimedOut 0ms
3 : 143.134.242.155 - TimedOut 0ms
3 : 110.29.95.203 - DestinationHostUnreachable 0ms
3 : 66.249.81.37 - Success 309ms
3 : 174.59.246.66 - TimedOut 0ms
3 : 163.176.88.190 - TimedOut 0ms
3 : 83.83.27.11 - TimedOut 0ms
3 : 19.156.14.248 - TimedOut 0ms
3 : 228.198.82.154 - TimedOut 0ms
3 : 89.90.185.217 - TimedOut 0ms
1 : 197.101.34.54 - TimedOut 0ms
---------
3 : 143.134.242.155 - TimedOut 0ms
3 : 26.99.52.159 - TimedOut 0ms
3 : 66.65.213.229 - TimedOut 0ms
3 : 110.29.95.203 - DestinationHostUnreachable 0ms
3 : 66.249.81.37 - Success 309ms
3 : 174.59.246.66 - TimedOut 0ms
3 : 83.83.27.11 - TimedOut 0ms
3 : 163.176.88.190 - TimedOut 0ms
3 : 89.90.185.217 - DestinationHostUnreachable 0ms
3 : 228.198.82.154 - TimedOut 0ms
3 : 19.156.14.248 - TimedOut 0ms
3 : 197.101.34.54 - TimedOut 0ms
---------
3 : 66.65.213.229 - TimedOut 0ms
3 : 26.99.52.159 - TimedOut 0ms
1 : 143.134.242.155 - TimedOut 0ms
3 : 110.29.95.203 - DestinationHostUnreachable 0ms
3 : 66.249.81.37 - Success 309ms
3 : 163.176.88.190 - TimedOut 0ms
3 : 174.59.246.66 - TimedOut 0ms
3 : 83.83.27.11 - TimedOut 0ms
3 : 89.90.185.217 - DestinationHostUnreachable 0ms
3 : 228.198.82.154 - TimedOut 0ms
3 : 19.156.14.248 - TimedOut 0ms
3 : 197.101.34.54 - TimedOut 0ms