我需要为我的一位客户的一些旧版cobol
数据库重新实现数据库连接驱动程序。构建应用程序的方式无法使用async/await
(就这样,我知道它很愚蠢)。
整个应用程序是一个ASP.NET API。
旧的驱动程序使用c ++ dll,inter-op方法中包含该dll。旧系统背后的想法是:使用一个连接到数据库的所有东西,让多个线程发送一个数据包,让一个线程接收答案并将它们委托给正确的线程。 为了使连接保持活动状态,需要向数据库发送某种ping消息并处理其pong消息。
我重新实现为,作为c#中的POC,建立一个连接,打开一个后台线程,并使用AutoResetEvents通知正确的线程,该答案已准备好进行处理。我将ReceiveTimeout设置为5秒,尽管没有人向服务器发送数据,但是接收超时帮助我将ping消息发送到服务器。
重写的原因是,单连接解决方案无法扩展。
因此,我的想法是使用套接字池,并在套接字上使用ReceiveAsync
和SocketAsyncEventArgs
。
到目前为止,该解决方案仍然有效,但效果不是很好。这里有一些问题:
ReceiveAsync
不兼容,是否有其他方法可以使用计时器发送我的ping消息ReceiveAsync
时,我是否仍可以使用普通的Send
发送数据,还是必须使用SendAsync
?ReceiveAsync
未收到所有必需的数据时,我可以使用Receive
来读取其余数据,还是对丢失的数据再次使用ReceiveAsync
更好? li>
答案 0 :(得分:1)
使用AutoResetEvents通知正确的线程,该答案已准备好进行处理。
我可以建议一个线程安全队列吗? server.R
还是BlockingCollection<T>
?
我将ReceiveTimeout设置为5秒,虽然没有人向服务器发送数据,但是接收超时帮助我将ping消息发送到服务器。
这很奇怪。我认为整个协议都是基于ping-pong的,否则使用接收超时来发送消息将不起作用。
我的想法是在套接字上使用套接字池和带有SocketAsyncEventArgs的ReceiveAsync
如果您不能使用BufferBlock<T>
/ async
,我建议您切换到await
/ Begin*
风格的异步API。从同步直接变为End*
是一个飞跃; SocketAsyncEventArgs
是套接字SocketAsyncEventArgs
编程的最困难形式。
除了计时器以外,还有其他方法可以发送我的ping消息
我建议您使用一个计时器;这是心跳消息的正常解决方案。所需的语义应该是“我们至少要经常发送数据”。因此,请使用可以在发送常规消息(不接收消息)时重置的计时器。
使用ReceiveAsync时,我是否仍可以使用普通的Send发送数据,还是必须使用SendAsync?
您应该能够对一个流使用同步,而对另一个流使用异步。我从来没有尝试过;我研究过的所有系统都是完全异步的。
当ReceiveAsync未接收到所有必需的数据时,我可以使用Receive读取其余数据,还是对丢失的数据再次使用ReceiveAsync更好?
这个问题对我来说意义不大。如果您正在异步读取,则不应阻塞调用线程。
此外,我认为这个问题是从错误的角度提出的。代码似乎想“接收下一条消息”,但这是从套接字读取数据的一种有问题的方式。相反,我建议您的代码具有一个循环,该循环从套接字不断地读取 ,并将该数据传递给另一种类型,该数据根据需要对其进行缓冲,并在消息完成时将其推出。
这是在负载下调试IIS进程时的已知行为吗?
我不希望如此,但是我没有太多的IIS负载测试经验。