【发布时间】:2018-04-12 01:29:18
【问题描述】:
我试图了解在 Windows 服务内启动的无限循环工作线程中异步/等待的语义。我是这方面的新手,所以在这里给我一些余地,我正在努力理解这个概念。
工作线程将永远循环(直到服务停止)并处理外部队列资源(在本例中为 SQL Server Service Broker 队列)。
工作线程使用的配置数据可以在服务运行时通过某种 IPC 在主服务线程上接收命令来更改。理想情况下,工作线程应在等待接收外部队列消息时处理这些配置更改。从服务代理读取本质上是异步的,您实际上是发出带有接收超时的“等待接收”TSQL 语句。
但我不太了解为此需要使用的控制流程。
假设我使用 concurrentQueue 将配置更改消息从主线程传递到工作线程。然后,如果我做了类似...
void ProcessBrokerMessages() {
foreach (BrokerMessage m in ReadBrokerQueue()) {
ProcessMessage(m);
}
}
// ... inside the worker thread:
while (!serviceStopped) {
foreach (configChange in configChangeConcurrentQueue) {
processConfigChange(configChange);
}
ProcessBrokerMessages();
}
...然后处理配置更改的 foreach 循环和代理处理功能需要“轮流”运行。具体来说,config-change-processing 循环不会在可能长时间运行的代理接收命令运行时运行。
我的理解是,在这种情况下,简单地将 ProcessBrokerMessages() 转换为异步方法对我没有帮助(或者我不明白会发生什么)。对我来说,由于我缺乏理解,最直观的解释似乎是,当我点击异步调用时,它会关闭并做它的事情,并且执行将继续外部 while 循环的重新启动......但这会意味着循环也会一遍又一遍地执行 ProcessBrokerMessages() 函数,即使它已经从前一个循环中的调用运行,这是我不想要的。
据我所知,这不会发生,尽管我只是“知道”这一点,因为我已经读过一些类似的东西。不是很懂。
可以说,现有的控制流程(即,没有异步调用)是可以的……如果配置更改影响 ProcessBrokerMessages() 函数(它们可以),那么在函数运行时配置不能被更改。但这似乎是这个特定示例的特定点。我可以想象配置更改正在更改线程所做的其他事情的情况,与 ProcessBrokerMessages() 调用无关。
有人可以在这里提高我的理解吗?什么才是正确的拥有方式
- 循环多个语句的代码块
- 其中一个(或一些)但并非所有这些语句都是异步的
- 并且异步操作一次只能执行一次
- 但在异步操作的单个实例运行时,执行应继续循环遍历其余语句
- 如果之前的调用已完成,则应在循环中再次调用异步方法
似乎我可以使用 BackgroundWorker 来运行接收语句,该语句在其工作完成时会翻转一个标志,但在我看来也很奇怪创建一个专门用于处理外部资源的线程,然后在该线程内,创建一个 BackgroundWorker 来实际完成这项工作。
【问题讨论】:
标签: multithreading asynchronous windows-services service-broker