2012-08-14 52 views
0

我有我的网络应用程序,即构建报告。在mvc3上的Web应用程序。而构建器是一个WCF服务。
我使用线程池来自动生成报告。
基本模型如下所示:
- Web应用程序在生成报告时发送请求。
- WCF服务创建工作者线程并向服务接受工作的Web应用程序发送响应。
- Web应用程序继续工作。WCF工作人员完成通知

我需要什么:当WCF工作线程将完成作业时,我需要通知 Web应用程序该作业已完成。

那么如何捕捉与我的web应用程序,回调(我使用MVC 3)

您能否提供实现这个逻辑的最简单的方法?

回答

0

有趣的问题。如果我了解您的要求,您需要允许用户在后台生成报表的同时继续其业务,然后通过AJAX向用户发送通知,告知用户该报表已准备就绪。

我相信你正朝着正确的方向前进。我建议利用WCF异步回调。有关MSDN的优秀启动文章可以从here获得。回调事件处理程序应该使用在最初将报告请求发送到WCF操作时创建的唯一缓存键来设置报告的缓存状态。

客户端通知可以使用报告状态轮询机制来实现,该机制使用由AJAX启用的相同唯一缓存键定期检查报告的状态。

异步WCF回调的一个简单的例子可以做一些事情,如以下几点:

ReportServiceClient reportSvcClient = new ReportServiceClient(); 
Guid reportStatusKey = Guid.NewGuid(); 
reportSvcClient.GenerateReportCompleted += new EventHandler<GenerateReportCompletedEventArgs>(ReportStatusCallback); 
reportSvcClient.GenerateReportAsync(reportStatusKey, <other operation paramters>); 

// Set initial report status to False 
// (recommend setting an appropriate expiration period) 
Cache.Insert(reportStatusKey.ToString(), false); 

// WCF callback static method which sets the report status in cache 
static void ReportStatusCallback(object sender, GenerateReportCompletedEventArgs e) 
{ 
    Cache[e.ReportStatusKey.ToString()] = e.IsComplete; 
} 
... 
public partial class GenerateReportCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs 
{ 
    private object[] results; 

    public GenerateReportCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) : 
     base(exception, cancelled, userState) 
    {  this.results = results;   } 

    public Guid ReportStatusKey 
    { 
     get   { 
      base.RaiseExceptionIfNecessary(); 
      return ((Guid)(this.results[0])); 
     } 
    } 
    public bool IsComplete 
    { 
     get { 
      base.RaiseExceptionIfNecessary(); 
      return ((bool)(this.results[1])); 
     } 
    } 
} 

客户端AJAX实现可以检查你相信任何频率是通过使用适当的报告缓存状态相同的ReportStatusKey。

0

为什么不使用svcutil/async为您的wcf服务生成异步代理。这样你就不需要在你的服务中使用你自己的工作线程,客户端只需注册回调。

0

WCF包含一些名为完成回调。在这里,只有在异步操作完成后,您的客户端才有一个方法要求WCF为您调用。

例如:

public class MyClient : IDisposable 
{ 
    BuilderClient _proxy = new BuilderClient(); 

    public void CallAsync(object input) 
    { 
     _proxy.BeginBuildReport(input, Oncompletion, null); 
    } 

    void OnCompletion(IAsyncResult result) 
    { 
     object output = _proxy.EndBuildReport(result); 
     //Do whatever you want with your output here. 
    } 

    public void Dispose() 
    { 
     _proxy.Close(); 
    } 
} 

这将允许你使用一个简单的事件驱动模型。