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

时间:2011-06-17 11:36:39

标签: c# asp.net wcf

我有一项并行执行的任务;例如,异步打印用户选择的文档。一种方法可能是使用工作线程。但考虑到数千个请求涌入Web服务器的情况,以及应用程序产生的另一个线程用于打印声音可怕。如果所有并发用户都开始打印怎么办?

因此我想避免工作线程的原因。

要解决此问题,我已将代码移到Web服务中;我正在调用PrintAsync()方法,并且已订阅OnPrintComplete以获得通知。现在我可以发送尽可能多的打印件而不用担心asp.net线程饥饿或阻塞请求。

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

我想不出可能的缺点,除了它将是一个Web服务。

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

2 个答案:

答案 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服务接收和处理。

设置和支持分布式事务非常容易。

MSMQ on MSDN

相关问题