使用Web服务避免线程的并行(异步)任务

本文关键字:并行 异步 任务 线程 Web 服务 使用 | 更新日期: 2023-09-27 17:59:40

我有一个并行执行的任务;例如异步打印用户选择的文档。一种方法可能是使用工作线程。但是,想到成千上万的请求涌入web服务器,而应用程序又产生了一个用于打印的线程的场景,听起来很可怕。如果所有并发用户都开始打印呢?

这就是我想要避免工作线程的原因。

为了解决这个问题,我在一个web服务中移动了代码;我正在调用PrintAsync()方法,并且我已经订阅了OnPrintComplete以获得通知。现在,我可以发送任意数量的打印,而不用担心asp.net线程不足或阻塞请求。

我知道web服务内部使用线程,但这是IOCP线程,这意味着它不会打扰asp.net工作线程。

我想不出可能的缺点,只是它将是一个web服务。

这是一个好方法吗?处理此功能的更好的替代版本是什么

使用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