我有一个并行执行的任务;例如异步打印用户选择的文档。一种方法是使用工作线程。但是,考虑到成千上万的请求涌入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默认情况下利用线程池。您不必担心每个操作都会使它自己的线程变得混乱,并最终耗尽机器资源。TPL还足够聪明,可以比不花费大量精力编写管道代码就可以自己完成的工作更高效地分布在盒中所有核心上。
第三,TPL可以与传统的异步编程模型(APM)结合使用,因此,如果您正在使用Streams(网络或文件)之类的东西,则可以使用它们的BeginRead/Write方法来最大程度地利用异步I / O,这将最大程度地释放异步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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3232 次 |
| 最近记录: |