2013-10-21 63 views
1

我的應用需要執行很多不同的請求(每秒1-2次)。我有一種連續運行的請求(RequestMade - > ResponseReceived - > RequestMade - > ...)。Windows商店應用:網絡請求延遲1分鐘

如果我進入另一個屏幕,我應該開始一組新的請求,只要我保持在該屏幕上,就會連續運行。

問題是,新的請求集(the initial request) is delayed with ~ 1 minute

下面是公佈用於執行請求的代碼。

請注意,該行打印出來的安慰,讓我們說12:00:

Debug.WriteLine("Writing RequestStream ("+_request.GetType().FullName + " | " + DateTime.Now.ToLocalTime()+")"); 

而行:

Debug.WriteLine("Request is posting.....(" + _request.GetType().FullName + " | " + DateTime.Now.ToLocalTime()+")"); 

Debug.WriteLine("Reading ResponseStream (" + _request.GetType().FullName + " | " + DateTime.Now.ToLocalTime() + ")"); 

在12:01打印(1分鐘後。 ...)

private class RequestResponseTask 
     { 
      private Uri _uri = null; 
      private string _uriAddress = null; 
      private WebRequest _webRequest = null; 
      private ARequest _request = null; 
      private JsonTextParser _parser = null; 
      private RequestState _requestState = null; 

      public RequestResponseTask(ARequest request) 
      { 
       // uri address 
       _uriAddress = CVSCustomRelease.Instance.ReleaseSettings.SelectedPrivateLabel.GetServer(LoginSettings.Instance.SelectedServer).Address 
        + CONTEXTUAL_REQUEST_PATH; 
       // uri 
       _uri = new Uri(_uriAddress); 

       // request 
       _request = request; 
       _parser = new JsonTextParser(); 
       _requestState = new RequestState(_request); 
      } 

      public void StartRequest() 
      { 
       Debug.WriteLine("Starting RUN.......(" + _request.GetType().FullName + " | " + DateTime.Now.ToLocalTime() + ")"); 
       Task.Factory.StartNew(() => 
        { 
         Debug.WriteLine("RUN Started. - for "+_request.GetType().FullName + " | " + DateTime.Now.ToLocalTime()); 
         _request.ResponseReceived = false; 
         Debug.WriteLine("Before WebRequest ("+_request.GetType().FullName + " | " + DateTime.Now.ToLocalTime()+")"); 
          _webRequest = WebRequest.Create(_uri); 

         Debug.WriteLine("after WebRequest (" + _request.GetType().FullName + " | " + DateTime.Now.ToLocalTime() + ")"); 
         _webRequest.ContentType = "text/x-gwt-rpc;charset=utf-8"; 
         _webRequest.Method = "Post"; 

         _requestState.Request = _webRequest; 

         // Start the Asynchronous 'BeginGetRequestStream' method call.  
         Debug.WriteLine("Writing RequestStream ("+_request.GetType().FullName + " | " + DateTime.Now.ToLocalTime()+")"); 
         IAsyncResult r = (IAsyncResult)_webRequest.BeginGetRequestStream(
          new AsyncCallback(PostRequest), _requestState); 

         _requestState.ResetEvent.WaitOne(); 
         Debug.WriteLine("Reading ResponseStream (" + _request.GetType().FullName + " | " + DateTime.Now.ToLocalTime() + ")"); 

         IAsyncResult asyncResp = (IAsyncResult)_webRequest.BeginGetResponse(
          new AsyncCallback(ReadResponse), _requestState); 
        }); 
      } 

      private void PostRequest(IAsyncResult asynchronousResult) 
      { 
       Debug.WriteLine("======================================================"); 
       Debug.WriteLine("Request is posting.....(" + _request.GetType().FullName + " | " + DateTime.Now.ToLocalTime()+")"); 

       // End the Asynchronus Request. 
       Stream streamResponse = _webRequest.EndGetRequestStream(asynchronousResult); 

       ARequest request = _requestState.OriginalRequest; 
       request.UpdateTimestampRealtime(); 
       string postData = request.GetPostData(); 

       EventsLog.Instance.WriteEvent("Request: " + postData); 

       // Create a string that is to be posted to the uri. 
       // Convert the string into a byte array. 
       byte[] byteArray = Encoding.UTF8.GetBytes(postData); 

       EventsLog.Instance.CurrentSession.AddTraficAmount(TraficType.Outgoing, byteArray.Length); 

       // Write the data to the stream. 
       streamResponse.Write(byteArray, 0, postData.Length); 
       streamResponse.Flush(); 
       Debug.WriteLine("Request POSTED."); 
       Debug.WriteLine("======================================================"); 
       _requestState.ResetEvent.Set(); 
      } 

      private async void ReadResponse(IAsyncResult asyncResult) 
      { 
       _requestState = (RequestState)asyncResult.AsyncState; 
       WebRequest myWebRequest = _requestState.Request; 

       WebResponse response = (WebResponse)myWebRequest.EndGetResponse(asyncResult); 
       Stream responseStream = response.GetResponseStream(); 

       StreamReader streamRead = new StreamReader(responseStream); 

       string responseString = await streamRead.ReadToEndAsync(); 

       byte[] byteArray = Encoding.UTF8.GetBytes(responseString); 
       EventsLog.Instance.CurrentSession.AddTraficAmount(TraficType.Incomming, byteArray.Length); 

       // build response object 
       JsonObject jsonObject = _parser.Parse(responseString); 
       EventsLog.Instance.WriteEvent("Response: " + jsonObject.ToString() + "\nFor Request: " + _requestState.OriginalRequest.RequestId + " | " +_requestState.OriginalRequest.GetType().FullName); 

       _requestState.ResetEvent.Reset(); 

       // notify listeners 
       _requestState.OriginalRequest.ResponseReceived = true; 
       _requestState.OriginalRequest.NotifyResponseListeners(jsonObject as JsonObjectCollection); 
      } 
     } 

執行的請求:

new RequestResponseTask(_request).StartRequest(); 
+0

看起來好像可能會出現一些限制,無論是在Windows中,還是在服務器上。考慮減少請求。您的用戶也會很開心,特別是如果他們使用通過3G連接的電池供電設備。 –

+0

這些請求是強制性的,因爲用戶希望看到更新「實時」。這是一個股票應用程序... –

+0

啊,股票應用程序。你確定這不是故意的嗎?這可能是一個長輪詢設計,服務器在回答前等待一分鐘。請參閱http://en.wikipedia.org/wiki/Push_technology#Long_polling –

回答

1

我的猜測:你的代碼塊會導致另一個線程(這是1分鐘來自哪裏)的超時,然後導致解除第一個線程的阻塞。

你的代碼中有類似BeginGetRequestStream和ResetEvent.WaitOne的東西 - 這不應該在你的Windows商店代碼中需要。嘗試使用WebClient的異步方法或HttpClient。使用await而不是WaitOne。

+0

該應用程序由2個組件組成:a .dll(可在Windows Phone和Windows之間移植8)和一個GUI組件。請求是在便攜式庫,所以我必須研究,如果HttpCient可以移植.. –

+0

BeginGetRequestStream是「有罪」在我的情況下......線程被阻止1分鐘 –

+0

HttpClient存在WP8。你需要通過Nuget來加載它:AFAIK你需要搜索「Microsoft HTTP Client」。 –