2013-10-21 32 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”。 –