Служба Wcf периодически блокирует, когда POST Http-файла работает в IFrame - PullRequest
0 голосов
/ 18 января 2012
This program has 2 components: 
     1. an HTML page containing 
       A- an  that contains a file upload
       B- javascript running in the containing page that is 
          on a 1-second timer to make a wcf call to get progress statistics.
     2. a Wcf Service that is contacted by the javascript every second.

Файл загружается в действие контроллера MVC3, которое считывает данные в виде фрагментов по 100 КБ и обновляет статистику Percent Complete в одноэлементной хэш-таблице (или словаре) по мере ее развития.

Между тем, служба Wcf (# 2 выше) получает статистику из синглтона и возвращает ее в формате JSON.

ПРОБЛЕМА: После нового развертывания все работает! Я могу загрузить файл из двух разных браузеров одновременно и наблюдать за прогрессом от 0% до 100% в каждом браузере. Но через некоторое время Wcf Services начинает блокироваться. Используя Fiddler, я вижу, что запросы GET javascript отправляются, но ответа не приходит. Javascript может выдать 10 из них до завершения загрузки файла, после чего все 10 ответов, наконец, вернутся, и все они говорят, что 100%, что означает, что код службы Wcf был заблокирован (или ранее) при попытке доступа к одиночному хеш-таблица.

Примечание. Сначала я пытался использовать состояние сеанса, чтобы сохранить значение прогресса и извлечь его из Wcf, но я узнал, что состояние сеанса для данного SessionId не может быть доступно одновременно двум потокам (т. Е. Моим действием потоком и потоком Wcf), поэтому я переключил его на использование статического синглтона. Я пробовал и Hashtable, и Dictionary <> как синглтон из-за их различной безопасности потоков.

Что удивительно, так это то, что некоторое время он работает очень хорошо, а затем, спустя несколько часов, когда я тестирую, он снова демонстрирует блокирующее поведение.

Примечание. Он развернут на общем хосте GoDaddy для Windows 4GH. Но такое же поведение возникает при развертывании на локальном экземпляре IIS 7.5.

The Wcf Service:
      AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
     [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
     public class OnoService : IOnoService
       . . .
     public UploadProgress GetUploadProgress(string controlid)
     {
        UploadProgress up = new UploadProgress();
        up.PercentComplete = SharedState.GetValue(controlid) as string;
        return up;
     }



The Containing page: Index.cshtml
    <divid="progressdiv"/>
    <input type="hidden" value="@Session.SessionID" name="controlId" id="controlId"/>
    <iframe src="UploadForm"/>

The IFrame UploadForm
      <form action="@Url.Content("~/MemberArea/UploadImage")" method="post" enctype="multipart/form-data">
         OwnerId <input type="text" id="ownerId" name="ownerId"   />
         <input type="hidden" value="@Session.SessionID" name="controlId" id="controlId"/>
         Image File <input type="file" id="image" name="image" />
         <input type="submit" />
      </form>

The Javascript:
       $(function () {
         monitorProgress();
       });

    function monitorProgress() {
      var controlId = $("#controlId").val();
      var url = "Services/OnoService.svc/GetUploadProgress/"+controlId;
      $.getJSON(url, function (data) {
            var items = [];
            var result =data.GetUploadProgressResult.PercentComplete + " %";
            $("#progressdiv").text(result);
      });
      setTimeout("monitorProgress()", 1000);   
    }


A few excerpts from web.config:

     &ltsessionState mode="InProc" cookieless="UseCookies" regenerateExpiredSessionId="false" />
    . . .
       &ltsystem.webServer>
          &ltstaticContent>
             &ltclientCache cacheControlMode="DisableCache" />
          &lt/staticContent>
    . . .
          &ltbehaviors>
             &ltserviceBehaviors>
                &ltbehavior name="">
                   &ltserviceMetadata httpGetEnabled="true" />
                   &ltserviceDebug includeExceptionDetailInFaults="true" />
                &lt/behavior>

SharedState.cs:
    public class SharedState
    {

        private static Hashtable store = null;
        private static Hashtable GetDictionary()
        {
            if (null == store)
                store = new Hashtable();
            return store;
        }

        public static void StoreValue(string key, object value)
        {
            GetDictionary()[key] = value;
        }
        public static object GetValue(string key)
        {
            if (GetDictionary().ContainsKey(key))
                return GetDictionary()[key];
            return null;
        }
    }

Итак, есть ли у кого-нибудь понимание того, почему служба Wcf будет блокироваться после того, как она будет работать правильно для нескольких одновременных попыток?

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