使用Web服务避免线程的并行(异步)任务
本文关键字:并行 异步 任务 线程 Web 服务 使用 | 更新日期: 2023-09-27 17:59:40
我有一个并行执行的任务;例如异步打印用户选择的文档。一种方法可能是使用工作线程。但是,想到成千上万的请求涌入web服务器,而应用程序又产生了一个用于打印的线程的场景,听起来很可怕。如果所有并发用户都开始打印呢?
这就是我想要避免工作线程的原因。
为了解决这个问题,我在一个web服务中移动了代码;我正在调用PrintAsync()
方法,并且我已经订阅了OnPrintComplete
以获得通知。现在,我可以发送任意数量的打印,而不用担心asp.net线程不足或阻塞请求。
我知道web服务内部使用线程,但这是IOCP线程,这意味着它不会打扰asp.net工作线程。
我想不出可能的缺点,只是它将是一个web服务。
这是一个好方法吗?处理此功能的更好的替代版本是什么
所以你已经描述了你是如何在客户端上进行异步调用的,实际上我还想问一些关于你实际上是如何完全异步的问题,但你的问题似乎更多的是关于如何在服务端尽可能高效,对吧?
如果您在服务操作中执行长时间运行或I/O绑定操作,那么您绝对必须开始利用WCF对异步服务操作的支持。现在,有很多方法可以做到这一点,但如果你在.NET 4.0上,没有比使用任务并行库(TPL)更好的方法了。
首先,通过将工作卸载到TPL线程,您可以释放WCF I/O线程来处理更多的调用。这样,您的长期运行的WCF操作就不会占用WCF字段其他操作的能力。
第二,TPL默认情况下利用a线程池。你不必担心每一个操作都会启动它自己的线程,并最终耗尽机器的资源。TPL也足够聪明,可以更有效地将工作分散到盒子上的所有核心,而无需在编写管道代码方面进行大量投资。
第三,TPL可以与传统的异步编程模型(APM)相结合,这样,如果您使用Streams
(网络或文件)之类的东西,您可以使用它们的BeginRead/Write
方法最大限度地利用异步I/O,这将在阻塞读/写时释放CPU线程。你绝对应该这样做以实现最大效率,即使你没有使用TPL,TPL只是让它更容易。
以下是如何使用TPL实现异步服务操作的"基本"示例:
public IAsyncResult BeginSomeLongRunningOperation(string sampleParam, AsyncCallback callback, object asyncState)
{
Task<int> processingTask = Task<int>.Factory.StartNew(
_ =>
{
... perform insanely long running operation here ...
return 42;
},
asyncState);
// If there was a callback, we have to invoke it after the processing finishes
if(callback != null)
{
processingTask.ContinueWith(
_ =>
{
callback(calculationTask);
},
TaskContinuationOptions.ExecuteSynchronously);
}
return processingTask;
}
public int EndSomeLongRunningOperation(IAsyncResult asyncResult)
{
return ((Task<int>)asyncResult).Result;
}
Microsoft消息队列(MSMQ)怎么样?
使用这种体系结构,您可以将所有打印请求排队,然后使用windows服务接收并处理一个又一个打印请求。
它非常容易设置并支持分布式事务。
MSDN 上的MSMQ