Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在C语言中执行并发任务#_C#_Multithreading_Asynchronous_Parallel Processing_Amazon Sqs - Fatal编程技术网

C# 在C语言中执行并发任务#

C# 在C语言中执行并发任务#,c#,multithreading,asynchronous,parallel-processing,amazon-sqs,C#,Multithreading,Asynchronous,Parallel Processing,Amazon Sqs,我有一项服务,需要尽快读取来自Amazon SQS的消息。我们预计交通会很拥挤,我希望能够每秒阅读超过10K的信息。不幸的是,我目前的速度是每秒10条左右。显然,我还有工作要做 这就是我正在使用的(转换为控制台应用程序以简化测试): private static int\u concurrentRequests; 私有静态int_maxConcurrentRequests; 公共静态void Main(字符串[]args){ _concurrentRequests=0; _maxConcurre

我有一项服务,需要尽快读取来自Amazon SQS的消息。我们预计交通会很拥挤,我希望能够每秒阅读超过10K的信息。不幸的是,我目前的速度是每秒10条左右。显然,我还有工作要做

这就是我正在使用的(转换为控制台应用程序以简化测试):

private static int\u concurrentRequests;
私有静态int_maxConcurrentRequests;
公共静态void Main(字符串[]args){
_concurrentRequests=0;
_maxConcurrentRequests=100;
var timer=new timer();
timer.appeased+=新的ElapsedEventHandler(OnTimedEvent);
时间间隔=10;
timer.Enabled=true;
Console.ReadLine();
timer.Dispose();
}
TimedEvent上的公共静态void(对象s、ElapsedEventArgs e){
如果(\u concurrentRequests<\u maxConcurrentRequests){
_concurrentRequests++;
ProcessMessages();
}
}
公共静态异步任务ProcessMessages(){
var manager=newmessagemanager();
manager.ProcessMessages();//这是一个异步方法,从SQS读入消息
_同意请求--;
}
我没有收到近100个并发请求,而且它似乎没有每隔10毫秒触发
OnTimedEvent

我不确定
Timer
是否是正确的方法。我对这种编码没有太多经验。在这一点上,我愿意尝试任何事情

更新

多亏了calebboyd,我离实现目标又近了一点。下面是一些非常糟糕的代码:

私有静态信号量lim\u locker;
公共静态void Main(字符串[]args){
_manager=newmessagemanager();
RunBatchProcessingForeverAsync();
}
专用静态异步任务RunBatchProcessingForeverAsync(){
_locker=新的信号量lim(10,10);
while(true){
线程线程=新线程(新的参数化线程启动(进程));
thread.Start();
}
}
私有静态异步无效进程(对象参数){
_locker.WaitAsync();
试一试{
wait_manager.ProcessMessages();
}
最后{
_锁定器释放();
}
}
使用此功能,我几乎可以每秒读取相当数量的消息,但问题是我的
ProcessMessages
调用从未完成(或者可能会在很长时间后完成)。我想我可能需要限制在任何时候运行的线程数量


关于如何改进此代码以使
ProcessMessages
有机会完成的建议?

我假设异步方法在线程池中排队,该线程池中的线程数与可用处理器的线程数相同。您可能会生成100个请求,但它们仍然由8个线程执行。尝试创建N个线程的数组并将其投入使用。

因为MessageManager对象上的
ProcessMessages
方法未被等待,我将假定它绑定到它在其中执行的同一线程。仅将函数标记为
async
不会将工作传递给新线程。在这种假设下,此代码实际上并不是使用多个线程执行的。您可以使用以下代码在更多线程池中执行代码

管理器对象可能无法处理并发使用。所以我在任务中创建了它。运行lambda。这也可能是昂贵的,因此不切实际

async Task RunBatchProcessingForeverAsync () {
    var lock = new SemaphoreSlim(initialCount: 10);
    while (true) {
        await lock.WaitAsync();
        Task.Run(() => {
            try {
                var manager = new MessageManager();
                manager.ProcessMessages();
            } finally {
                lock.Release();
            }
        });
    }
}

我已经有一段时间没有写C了,但这应该可以同时、重复、永远地运行你的方法10次。

正如@caleboyd所建议的,你必须首先使你的线程异步。现在,如果你走到这里-
,您将看到一个异步线程足以非常快速地共享网络资源。如果您能够在一个请求中从amazon获取多条消息,那么您的生产者线程(对amazon进行异步调用的线程)就可以了——它每秒可以发送数百条请求。这不会成为你的瓶颈。但是,处理接收到的数据的延续任务被交给线程池。在这里,你有机会遇到瓶颈——假设每秒有100条响应,每条响应包含100条消息(达到10K毫秒/秒的近似值)。每秒钟有100个新任务,每个任务都需要线程处理100条消息。现在有两种选择:(1)这些消息的处理不受CPU的限制-您只需将它们发送到您的数据库,或者(2)执行CPU消耗计算,例如科学计算、序列化或一些繁重的业务逻辑。如果(1)是您的情况,那么瓶颈将被向后推到您的身上。如果为(2),则您别无选择,只能放大/缩小或优化计算。但是,如果实现正确的话,瓶颈可能不是生产线程(参见上面的链接中的示例)。

计时器有一个限制,最多只能每15.6毫秒触发一次。这是计时器.NET实现的一个限制。声称是异步的代码没有
wait
——这很奇怪。考虑更新你的代码看起来更真实。这是一个非常重要的问题,用多线程来确定什么是可能的。如果你在一个线程上运行请求,每秒你能处理多少条消息?你的首要目标是尽可能快地把Amazon SQL连接起来吗?考虑缓冲这些消息,并将它们插入到BUK中的DB中,调用<代码> THealPoal.GETMax线程返回1023个可用的线程。我有一个处理器,有四个内核和8个超线程。@Enigmativity这并不意味着Robert Hudjakov是完全错误的-据我所知,在理论上纯异步程序中,线程池不会创建超过8个(在您的情况下)线程来处理所有排队的任务,即使缓冲区已饱和。不过,我可能错了。我从未见过