0

background agent에서 http web request을 보내려고합니다. 코드는 다음과 같습니다. json_Callback이 실행되지 않으며 내 요청이 서버에 도달하지 않습니다. 모든 예외 처리를 수행했지만 그 중 아무 것도 트리거되지 않습니다.스케줄/백그라운드 에이전트에서 httpwebrequest를 보내십시오.

백그라운드 에이전트에서 웹 요청을 보내는 방법은 무엇입니까?

WebClient를 사용하여 전화 걸기 매우 좋은 HttpClient를 NuGet 패키지가되기 전에 (이 작성되었습니다 : 내 배경 에이전트에서 HTTP 요청을하는 방법이 여기에 당신을 도울 여부,하지만 않을 경우

protected override void OnInvoke(ScheduledTask task) 
    { 
     string toastMessage = "Testing Push running."; 
     ShellToast toast = new ShellToast(); 
     toast.Title = "Background Agent Sample"; 
     toast.Content = toastMessage; 
     toast.Show(); 

     try 
     { 
      string token = "no token"; 
      appSettings.TryGetValue("newToken", out token); 
      toastMessage = "New Push running."; 
      toast = new ShellToast(); 
      toast.Title = "Background Agent Sample"; 
      toast.Content = token; 
      toast.Show(); 

      if (!String.IsNullOrEmpty(token)) 
       postTokenToServer(token); 

      _event = new ManualResetEvent(false); 
      _event.WaitOne(); 
     } 
     catch (Exception e) 
     { 
      toastMessage = e.Message; 
      toast = new ShellToast(); 
      toast.Title = "a"; 
      toast.Content = toastMessage; 
      toast.Show(); 
     } 

     #if DEBUG_AGENT 
     ScheduledActionService.LaunchForTest(
         task.Name, TimeSpan.FromSeconds(1)); 
     #endif 
     toast = new ShellToast(); 
     toast.Title = "task complete"; 
     toast.Show(); 

     NotifyComplete(); 
    } 



    private void postTokenToServer(string token) 
    { 
     ShellToast toast = new ShellToast(); 
     toast.Title = "is net available"; 
     toast.Content = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable().ToString(); 
     toast.Show(); 

     if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) 
     { 
      HttpWebRequest req = HttpWebRequest.Create(new Uri(BASE + "/account/device")) as HttpWebRequest; 
      req.Headers["Cookie"] = "user=" + appSettings["token"] + ";uid=" + (string)appSettings["uid"]; 

      toast.Title = "Cookies token"; 
      toast.Content = (string)appSettings["token"]; 
      toast.Show(); 
      toast.Title = "uid"; 
      toast.Content = (string)appSettings["uid"]; 
      toast.Show(); 

      req.Method = "POST"; 
      req.ContentType = "application/json"; 
      req.BeginGetRequestStream(new AsyncCallback(setParams_Callback), req); 
     } 
     else 
      _event.Set(); 
    } 

    private void setParams_Callback(IAsyncResult result) 
    { 
     string uri = "no token"; 
     appSettings.TryGetValue("newPushToken", out uri); 
     var req = (HttpWebRequest)result.AsyncState; 
     Stream postStream = req.EndGetRequestStream(result); 

     JObject data = new JObject(); 
     data.Add("dev_token", uri); 
     data.Add("dev_type", "windows"); 

     ShellToast toast = new ShellToast(); 
     toast.Title = "Posting Now"; 
     toast.Content = data.ToString(Newtonsoft.Json.Formatting.None); 
     toast.Show(); 

     using (StreamWriter sw = new StreamWriter(postStream)) 
     { 
      string json = data.ToString(Newtonsoft.Json.Formatting.None); 
      sw.Write(json); 
     } 
     postStream.Close(); 

     try 
     { 
      req.BeginGetResponse(new AsyncCallback(json_Callback), req); 
     } 
     catch(Exception e) 
     { 
      toast.Title = "Posting Error"; 
      toast.Content =e.Message; 
      toast.Show(); 
      _event.Set(); 
     } 

     toast.Title = "Posted"; 
     toast.Content = DateTime.UtcNow.ToShortTimeString(); 
     toast.Show(); 
    } 

    private void json_Callback(IAsyncResult result) 
    { 
     ShellToast toast = new ShellToast(); 
     toast.Title = "completed"; 
     toast.Show(); 
     _event.Set(); 
    } 
+1

'_event.WaitOne를(); ' 기다리고있는 현재 쓰레드가 멈추게되어 결코 완료되지 않을 것입니다. 개인적으로, 나는 async/await을 사용하여'postTokenToServer' 메소드를 다시 작성하고'WebClient()'를 사용하여보다 깔끔하고 적은 코드를 사용한다. –

+0

내가 옳은 것이 그게 맞습니까? 응답을 받기 전에 메인 bg 태스크 스레드를 종료하고 싶지 않습니다. 그리고 왜 웹 클라이언트가 웹 요청 작업에 사용해야합니까? –

+0

'WebClient'를 사용하면 콜백 필요성을 없애고 코드를 단순화 할 수 있습니다. 또한 –

답변

0

확실하지입니다 사용 가능) :

public async Task<string> GetArrivalsAsync(IEnumerable<int> locations) 
    { 
     var request  = new WebClient(); 
     var requestUri = GetArrivalsRequestUri(locations); 
     var response = await request.DownloadStringTask(requestUri); 

     return response; 
    } 

비동기 코드 작성을 크게 단순화 한 async/await 키워드를 사용합니다. 대부분의 작업은이 확장 메소드에서 WebClient으로 이루어집니다. 나는 그것을 발견 한 곳 (아마 여기에 StackOverflow에 있었지만) 내가 확장 방법에 대한 크레딧을받을 수 없어,하지만 오랜만이야 내가 기억하지 수

/// <summary> 
/// The WebClientExtensions class provides extension methods for the <see cref="System.Net.WebClient"/> class. 
/// </summary> 
public static class WebClientExtensions 
{ 
    /// <summary> 
    /// This extension method is used to asynchronously download data from a URI 
    /// and return that data in the form of a string. 
    /// </summary> 
    /// <param name="webClient">The <see cref="System.Net.WebClient"/> instance used to perform the download.</param> 
    /// <param name="uri">The URI to download data from.</param> 
    /// <returns>The <see cref="Task"/> used to perform the operation.</returns> 
    public static Task<string> DownloadStringTask(this System.Net.WebClient webClient, Uri uri) 
    { 
     if (uri == null) 
     { 
      throw new ArgumentNullException("uri"); 
     } 

     var tcs = new TaskCompletionSource<string>(); 

     webClient.DownloadStringCompleted += (s, e) => 
      { 
       if (e.Error != null) 
       { 
        tcs.SetException(e.Error); 
       } 
       else 
       { 
        tcs.SetResult(e.Result); 
       } 
      }; 

     webClient.DownloadStringAsync(uri); 
     return tcs.Task; 
    } 
} 
+0

을 기다릴 수 있지만 게시물을 req해야합니다. –

+0

@MilanAggarwal은 UploadDataAsync –

+0

을 사용하도록 코드를 변경합니다.이 경우 내 서버가 제대로 인증 할 수 있도록 헤더 정보를 어떻게 추가 할 수 있습니까? –