我有一项并行执行的任务;例如,异步打印用户选择的文档。一种方法可能是使用工作线程。但考虑到数千个请求涌入Web服务器的情况,以及应用程序产生的另一个线程用于打印声音可怕。如果所有并发用户都开始打印怎么办?
因此我想避免工作线程的原因。
要解决此问题,我已将代码移到Web服务中;我正在调用PrintAsync()
方法,并且已订阅OnPrintComplete
以获得通知。现在我可以发送尽可能多的打印件而不用担心asp.net线程饥饿或阻塞请求。
我知道Web服务内部使用线程,但那是IOCP线程,这意味着它不会打扰asp.net工作线程。
我想不出可能的缺点,除了它将是一个Web服务。
这是一个好方法吗?处理此功能的更好 备用版本会是什么?
答案 0 :(得分:5)
所以你已经描述了你是如何在客户端上进行异步调用的,实际上还有一些问题我会询问你实际上是如何在那里完全异步,但似乎你的问题更多的是如何成为在服务方面尽可能高效,对吧?
如果您在服务操作中执行长时间运行或I / O绑定操作,则绝对必须开始利用WCF对asynchronous service operations的支持。现在,有很多方法可以做到这一点,但是如果你使用.NET 4.0,那么没有比使用Task Parallel Library(TPL)更好的方法了。
首先,通过将工作卸载到TPL线程,您可以释放WCF I / O线程来处理更多调用。这样,长时间运行的WCF操作不会限制WCF对其他操作进行记录的能力。
其次,TPL默认使用线程池。您不必担心每个操作都会激活它自己的线程并最终使资源机器匮乏。 TPL也足够智能,可以比你自己做的更有效地在盒子上传播所有核心的工作,而无需花费大量的代价来编写管道代码。
第三,the TPL can be combined with the traditional Asynchronous Programming Model (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;
}
答案 1 :(得分:1)
Microsoft Message Queue(MSMQ)怎么样?
使用此架构,您可以排队所有打印请求,然后使用Windows服务接收和处理。
设置和支持分布式事务非常容易。