Async / Await HttpClient请求

时间:2013-11-19 08:28:07

标签: c# asynchronous windows-8 httpclient

我在类中有下一个代码,这个类以XML格式从服务器获取数据:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Windows.Security.Cryptography.Certificates;
using Windows.Storage;
using Windows.Storage.Streams;

namespace TestProj.WebServiceModels
{
public class MyClient
{
     async public static Task<string> fetchContentAsync()
    {
        string url = "https://blabla.com/test/data?format=xml";
        HttpClientHandler aHandler=new HttpClientHandler();
        aHandler.ClientCertificateOptions=ClientCertificateOption.Automatic;
        HttpClient aClient=new HttpClient(aHandler);
        Uri requestUri=new Uri(url);
        HttpRequestMessage request=new HttpRequestMessage(HttpMethod.Get, requestUri);
        var result=await aClient.GetAsync(requestUri, HttpCompletionOption.ResponseContentRead);
        var responseHeader=result.Headers;
        var responseBody=await result.Content.ReadAsStringAsync();
        return responseBody;        
    }
}
}

在我的主页面上,我有一个触发get方法和IT失败的功能!!!:

 public MainPage()
    {
        this.InitializeComponent();
        fillChartsObject();
    }

private async void fillChartsObject()
    {
        try
        {
            var response = await MyClient.fetchContentAsync();
            responseString = response.ToString();
        }
        catch
        {
            var dlg = new MessageDialog("You are totaly screwed!");
            dlg.ShowAsync();
        }
    }

但是当我在按钮上执行此操作时,单击它会运行!怎么可能?!如何解决?

当它失败时 - 它不会问我使用哪个证书,在其他情况下也是如此;

错误:     请求已中止:无法创建SSL / TLS安全通道。

System.Net.Http.HttpRequestException не обработано пользовательским кодом
HResult=-2146233088
Message=An error occurred while sending the request.
Source=mscorlib
StackTrace:
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at     System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SaC.WebServiceModels.MyClient.<fetchContentAsync>d__0.MoveNext() in c:\Users\C5195923\Documents\Visual Studio 2012\Projects\SaC\SaC\WebServiceModels\MyClient.cs:line 31
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SaC.MainPage.<fillChartsObject>d__96.MoveNext() in c:\Users\foma\Documents\Visual Studio 2012\Projects\SaC\SaC\MainPage.xaml.cs:line 1546
  InnerException: System.Net.WebException
   HResult=-2146233079
   Message=The request was aborted: Could not create SSL/TLS secure channel.
   Source=System
   StackTrace:
        at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
        at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
   InnerException:

代码2:

protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        fillChartsObject();
    }



 private async void fillChartsObject()
    {

        String responseString = "";
            var response = await MyClient.fetchContentAsync();
            responseString = response.ToString();

    }

错误:

   System.Net.Http.HttpRequestException не обработано пользовательским кодом
   HResult=-2146233088
   Message=An error occurred while sending the request.
   Source=mscorlib
   StackTrace:
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SAPSalesCentral.WebServiceModels.MyClient.<fetchContentAsync>d__0.MoveNext() in c:\Users\C5195923\Desktop\NewNewRevision\SAPSalesCentral\SAPSalesCentral\WebServiceModels\MyClient.cs:line 31
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at SAPSalesCentral.MainPage.<fillChartsObject>d__94.MoveNext() in c:\Users\foma\Desktop\NewNewRevision\SAPSalesCentral\SAPSalesCentral\MainPage.xaml.cs:line 1539
  InnerException: System.Net.WebException
   HResult=-2146233079
   Message=The request was aborted: Could not create SSL/TLS secure channel.
   Source=System
   StackTrace:
        at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
        at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
   InnerException:

附加功能:

ShowLoadingScreen(); // displays semi-transparent background over the whole form and progressRing (native Windows 8 spinner) on it.
GetSettings(); //gets data from local settings storage;
CheckFileExists(); // ASYNC! Checks if data is already stored on a device, if not, gets from web
fillListBox(); // Just populates listbox with hardcoded data;
PopulateHelpMenu(); // Just populates listbox with hardcoded data;
(App.Current as App).Main = this;

修改

public MainPage()
    {
        this.InitializeComponent();

        //#region Initialization
        ShowLoadingScreen();
        //fillChartsObject();
        GetSettings();
        CheckFileExists();
        fillListBox();
        PopulateHelpMenu();
        (App.Current as App).Main = this;
        //#endregion
    }


 protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        await Task.Delay(5000);
        await fillChartsObject(); 
        //await fillChartsObject();
        //fillChartsObject();
        ////dtm = DataTransferManager.GetForCurrentView();
        ////dtm.DataRequested += OnDataRequested;
        ////SettingsPane.GetForCurrentView().CommandsRequested += BlankPage_CommandsRequested;
    }

         private async void CheckFileExists()
    {
        //vpnAvailability = await VPN.Check(); //When i uncoment this - it fails again. This just sends request to a link, if it fails = no VPN if not = is VPN.
        ro = new List<RootObject>();
        StorageFile File;
        try
        {
            #region If file exists
            File = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("UserData.txt");
            if (File != null)
            {
                string JSON = await FileIO.ReadTextAsync(File);
                if (JSON != "")
                {
                    //If file exists get data
                    try
                    {
                        ro = JsonConvert.DeserializeObject<List<RootObject>>(JSON);
                        fillGamificationLine(ro);
                    }
                    catch
                    {
                        getGamificationDataFromServer();
                    }
                }
                else
                {
                    throw new FileNotFoundException();
                }
            }
            #endregion
        }
        catch (FileNotFoundException)
        {
            //If file doesn't exist - get data from server
            getGamificationDataFromServer();
        }
    }

 //The idea was that when all UserData is being populated from server or locally, the request of table data (only from service) is being proceeded parallel.

感谢Kris Vandermotten,我遇到了这种魔力:

失败:

protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        await fillChartsObject(); 
    }

使用:

protected async override void OnNavigatedTo(NavigationEventArgs e)
    {
        await Task.Delay(1);
        await fillChartsObject(); 
    }

1 个答案:

答案 0 :(得分:1)

这可能是一个时间问题,您的代码运行得太早。您应该首先完成UI初始化代码。

试试这个:

public MainPage()
{
    this.InitializeComponent();
}

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    // allow other queued messages to be processed first
    // this may work as well: await Task.Yield();
    await Task.Delay(1);
    // now continue
    await fillChartsObject();
}

private async void fillChartsObject()
{
    try
    {
        var response = await MyClient.fetchContentAsync();
        responseString = response.ToString();
    }
    catch
    {
        var dlg = new MessageDialog("You are totally screwed!");
        dlg.ShowAsync();
    }
}