当前位置: 首页 > 编程语言 > C#

始终在Windows服务上运行线程共享

时间:2023-04-10 11:07:33 C#

始终在Windows服务上运行线程我正在编写一个Windows服务,它将启动多个工作线程,这些工作线程将侦听AmazonSQS队列并处理消息。大约会有20个线程监听10个队列。线程必须始终运行,这就是为什么我倾向于实际使用实际线程作为工作循环而不是线程池线程。这是一个顶级实现。Windows服务将启动多个工作线程,每个工作线程都将监听其队列并处理消息。protectedoverridevoidOnStart(string[]args){for(inti=0;i<_workers;i++){newThread(RunWorker).Start();}}这是作业的实现publicasyncvoidRunWorker(){while(true){//..从amazonsqs同步获取消息..大约20msvarmessage=sqsClient.ReceiveMessage();尝试{awaitPerformWebRequestAsync(message);等待InsertIntoDbAsync(消息);}catch(SomeExeception){//...log//继续重试继续;}sqsClient.DeleteMessage();我知道我可以对Task.Run做同样的事情,并在线程池线程上执行它,而不是启动一个线程,但我看不出原因,因为每个线程都会一直运行。你看到这个实现有什么问题吗?保持线程始终以这种方式运行有多可靠,我该怎么做才能确保每个线程始终运行?现有解决方案的一个问题是您正在以一种火力全开的方式调用RunWorker,即newThread(RunWorker).Start(),尽管是在新线程上(即newThread(RunWorker).Start())。RunWorker是一个异步方法,当执行点到达第一个await(即awaitPerformWebRequestAsync(message))时,它将返回给调用者。如果PerformWebRequestAsync返回挂起的任务,RunWorker将返回并且您刚刚启动的新线程将终止。我认为您根本不需要新线程,只需使用AmazonSQSClient.ReceiveMessageAsync并等待其结果即可。另一件事是你不应该使用asyncvoid方法,除非你真的不关心跟踪异步任务的状态。请改用异步任务。您的代码可能如下所示:List_workers=newList();CancellationTokenSource_cts=newCancellationTokenSource();protectedoverridevoidOnStart(string[]args){for(inti=0;i现在,要停止所有挂起的worker,您可以简单地执行此操作(从主“请求调度程序”线程):_cts.Cancel();试试{Task.WaitAll(_workers.ToArray());}catch(AggregateExceptionex){ex.Handle(inner=>innerisOperationCanceledException);}请注意,ConfigureAwait(false)对于Windows服务是可选的,因为没有同步上下文默认情况下在初始线程上。但是,我会保持这种方式以保持代码独立于执行环境(对于存在同步上下文的情况)。最后,如果由于某种原因你不能使用ReceiveMessageAsync,或者你需要调用另一个阻塞API,或者只是在RunWorkerAsync开始时做一些CPU密集型工作,只需用Task.Run包装它(而不是包装整个RunWorkerAsync):varmessage=awaitTask.Run(()=>sqsClient.ReceiveMessage()).ConfigureAwait(false);好吧,我使用在服务中实例化并传递给工作人员的CancellationTokenSource。您的while语句将变为:while(!cancellationTokenSource.IsCancellationRequested){//代码的其余部分}这样您就可以从OnStop服务方法中取消所有工作人员。此外,您应该注意:如果您在线程外部使用线程状态,则可能会抛出ThreadStateException或ThreadInterruptedException或其中之一。因此,您希望处理适当的线程重新启动。worker是否需要在迭代之间不间断地运行?我会在那里睡觉(即使是几毫秒),这样他们就不会无缘无故地让CPU饿死。您需要处理ThreadStartException并在发生时重新启动worker。除此之外,只要服务运行(一天、几周、几个月),这10个踏板没有理由不运行。以上就是C#学习教程:始终在Windows服务上运行线程分享全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: