2011-06-17 75 views
2

我有一个并行执行的任务;例如异步打印用户选择的文档。一种方法可能是使用工作线程。但考虑到成千上万的请求涌入Web服务器的情况,以及应用程序正在产生一个打印线程,这听起来很可怕。如果所有的并发用户都开始打印呢?使用Web Service避免线程的并行(异步)任务

所以是我想避免工作线程的原因。

为了解决这个问题,我将代码移到了一个web服务中;我打电话给PrintAsync()方法,并且我订阅了OnPrintComplete以获得通知。现在,我可以发送尽可能多的打印件,而无需担心asp.net线程挨饿或阻塞请求。

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

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

这是一个很好的方法吗?本来应该是 更好 替代处理此功能的版本?

+4

什么问题? – 2011-06-17 11:38:03

回答

4

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

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

怎么样的微软消息队列(MSMQ)?

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

建立和支持分布式事务非常简单。

MSMQ on MSDN