【问题标题】:Parallel(Async) tasks using Web Service to avoid Threads并行(异步)任务使用 Web 服务来避免线程
【发布时间】:2011-06-17 11:36:38
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 使用更好这个词并不能帮助这个问题得到绝对的回答。
  • 什么是调用 PrintAsync 方法 - 智能客户端或 Web 请求?如果是 Web 请求,当 OnPrintcomplete 事件触发时会发生什么 - 在此期间请求是否被阻塞?
  • @Richard:我在一个 asp.net 网络应用程序中调用这个方法。
  • @Mr.失望:替换为alternate
  • 您的页面处理在 PrintAsync 和 OnPrintComplete 之间做了什么?

标签: c# asp.net wcf


【解决方案1】:

所以你已经描述了你是如何在客户端上进行异步调用的,实际上我还想问一些关于你在那里实际上是如何完全异步的问题,但看起来你的问题更多是关于如何在服务方面尽可能高效,对吧?

如果您在服务操作中执行长时间运行或 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;
}

【讨论】:

    【解决方案2】:

    Microsoft 消息队列 (MSMQ) 怎么样?

    通过这种架构,您可以将所有打印请求排队,然后使用windows服务来接收和处理。

    它很容易设置并支持分布式事务。

    MSMQ on MSDN

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多