ASP.NET MVC2应用程序调用WCF双工服务

时间:2010-10-02 15:38:31

标签: wcf asp.net-mvc-2

我有一个MVC2应用程序。基本上,在我的Bill视图中,我希望用户单击“Request Bill”并调用WCF服务。然后,该服务返回一个带有欠款的回调。我有2个问题。

  1. 来自客户端的双工方法回调未执行或未被调用。这是间歇性的。有时它被调用,有时它不会
  2. 第二个问题是无论回调方法是否执行,页面或应用程序在返回视图后很快就会关闭(在2-3秒内)。
  3. 在我看来,我有以下内容:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
    
    <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
        Bill
    </asp:Content>
    
    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
        <h2>Bill Summary:</h2>
    
        <td>
         <%: ViewData["ProcessingMessage"] %>
        </td>
        <table>
            <tr>
                <th>
    
                    Username: 
                </th>
                <th>
                    Total Number of Calls: 
                </th>
                <th>
                    Amount to be Paid: 
                </th>
                <th>&nbsp;</th>
            </tr>
         <td>
        <%: ViewData["Username"] %>
        </td>
        <td>
        <%: ViewData["CallsCount"] %>
        </td>
         <td>
        <%: ViewData["TotalAmount"] %>
        </td>
        </table>
    </asp:Content>
    

    在我的控制器中,我有以下方法:

    public class TelephoneController : Controller
        {
    BillingCallback proxy = new BillingCallback();
     public ActionResult Bill()
            {
                ViewData["ProcessingMessage"] = "Processing Request.....";
                proxy.CallService(User.Identity.Name);
                return View();
            }
    }
    

    我为回调创建了一个类:

    public class BillController : Controller
        {
            private const double amountPerCall = 0.25;
            public double calcBill()
            {
                double total = amountPerCall;
                Log p = new Log();
                return total;
            }
            public ActionResult Index()
            {
                return View();
            }
        }
    

    现在服务:

    [ServiceContract(CallbackContract = typeof(IBillCallBack))]
        public interface IBill
        {
            [OperationContract(IsOneWay = true)]
            void GetBilling(string username);
        }
        public interface IBillCallBack
        {
            [OperationContract(IsOneWay = true)]
            void CalculateBilling(string message);
        }
    
    [ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple)]
        class Bill : IBill
        {
            public void GetBilling(string username)
            {
                IBillCallBack callback = OperationContext.Current.GetCallbackChannel<IBillCallBack>();
                ThreadPool.QueueUserWorkItem(new WaitCallback(SendOperationToClient), callback);
            }
            public void SendOperationToClient(object stateinfo)
            {
                IBillCallBack callback;
                callback = stateinfo as IBillCallBack;
                string s = Thread.CurrentThread.ManagedThreadId.ToString();
                callback.CalculateBilling("username");
            }
        }
    

    有什么想法吗?

1 个答案:

答案 0 :(得分:2)

这是竞争条件和双工服务的错误使用。

您的代码中会发生什么:

  • 您有一个调用服务操作的控制器
  • 服务操作启动新线程并返回
  • 您的控制器继续处理并返回ViewResult
  • 在服务流程代码上的平均时间工作者线程并开始回调
  • 现在,如果工作人员足够快,则会调用回调
  • 如果工作人员的速度不够快,则您的视图已经呈现,并且计算中的更改将丢失
  • 此外,如果工作人员真的很慢,控制器也会从内存和代理中释放=&gt;无法调用回调,这可能会导致服务异常

不要在Web应用程序中使用双面服务。这没有任何意义,因为您仍然需要等待回调 - 我没有看到使用请求/响应模式调用您的服务与调用计算作为常用方法有任何不同。