Приложение ASP.NET MVC2, вызывающее дуплексную службу WCF - PullRequest
2 голосов
/ 02 октября 2010

У меня есть приложение MVC2.По сути, в моем представлении «Билл» я хочу, чтобы пользователь нажал «Запросить счет», и он вызывает службу WCF.Затем служба возвращает обратный вызов с причитающейся суммой.У меня 2 проблемы.

  1. Обратный вызов метода дуплексного режима от клиента не выполняется или не вызывается.Это происходит периодически.Иногда он вызывается, а иногда нет
  2. Вторая проблема заключается в том, что независимо от того, выполняется метод обратного вызова или нет, страница или приложение закрываются вскоре (в течение 2-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 Ответ

2 голосов
/ 02 октября 2010

Это состояние гонки и неправильное использование дуплексного сервиса.

Что происходит в вашем коде:

  • У вас есть контроллер, который вызывает сервисную операцию
  • Сервисная операция запускает новый поток и возвращает
  • Ваш контроллер продолжает обработку и возвращает ViewResult
  • Тем временем рабочий поток на коде процесса службы и запускает обратный вызов
  • Теперь, если работник достаточно быстр, ваш обратный вызов называется
  • Если работник недостаточно быстр, ваш Просмотр уже обработан и изменения в расчете потеряны
  • Более того, если работник работает очень медленно, контроллер освобождается из памяти и через прокси-сервер => обратный вызов не может быть вызван, что, вероятно, приведет к исключению в службе

Просто не используйте дуплексный сервис в веб-приложении. Это не имеет смысла, потому что вам все еще приходится ждать обратного вызова - я не вижу разницы в вызове вашей службы с шаблоном запроса / ответа и чем в вызове вычисления в качестве распространенного метода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...