2017-02-21 18 views
0

В нашем приложении Xamarin Forms мы должны загружать много данных из нескольких API'ов. Самый простой способ - использовать HttpClient непосредственно для PCL, но я получаю эту ошибку, когда их несколько сотен.Почему я получаю исключение NullReferenceException при создании экземпляра System.Net.Http.HttpClient()?

С этой страницей я мог бы воспроизвести эту проблему в новом проекте PCL.

using System; 
using Xamarin.Forms; 

namespace HTTPTest 
{ 
public class HTTPTestPage : ContentPage 
{ 
    int Index = 0; 

    public HTTPTestPage() 
    { 
     Content = new Label 
     { 
      Text = "HTTP Test" 
     }; 
    } 

    protected override void OnAppearing() 
    { 
     base.OnAppearing(); 
     StartLoading(); 
    } 

    void StartLoading() 
    { 
     for (int i = 0; i < 400; i++) 
     { 
      if (string.IsNullOrEmpty(LoadStringFromEndpoint("https://google.de"))) 
      { 
       break; 
      } 
     } 
    } 

    public string LoadStringFromEndpoint(string url) 
    { 
     System.Diagnostics.Debug.WriteLine("LoadFromEndpoint: " + url); 
     try 
     { 
      Index++; 
      var client = new System.Net.Http.HttpClient(); 
      return client.GetStringAsync(url).Result; 
     } 
     catch (NullReferenceException ex) 
     { 
      System.Diagnostics.Debug.WriteLine($"{ex.Message} at Index: {Index}"); 
      System.Diagnostics.Debug.WriteLine(ex.StackTrace); 
     } 
     return string.Empty; 
    } 
} 
} 

И это результат:

LoadFromEndpoint: https://google.de 
Object reference not set to an instance of an object at Index: 123 
    at System.Net.Http.RuntimeOptions.Read() [0x0002c] in /Users/builder/data/lanes/3985/9d6e1ab1/source/xamarin-macios/src/ObjCRuntime/RuntimeOptions.cs:229 
    at System.Net.Http.RuntimeOptions.GetHttpMessageHandler() [0x00000] in /Users/builder/data/lanes/3985/9d6e1ab1/source/xamarin-macios/src/ObjCRuntime/RuntimeOptions.cs:265 
    at System.Net.Http.HttpClient.GetDefaultHandler() [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.121/src/mono/mcs/class/System.Net.Http/HttpClientEx.cs:36 
    at System.Net.Http.HttpClient..ctor() [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/10.4.0.121/src/mono/mcs/class/System.Net.Http/HttpClientEx.cs:24 
    at HTTPTest.HTTPTestPage.LoadStringFromEndpoint (System.String url) [0x00020] in [...]HTTPTest/HTTPTestPCL/HTTPTestPage.xaml.cs:41 

Если я получаю это исключение один раз и загрузки файла после этого, я также получит System.IO.Exception (слишком много открытых файлов). Есть ли способ исправить это (желательно, не используя его)?

ответ

6

Нельзя создавать много экземпляров HttpClient. Это объект, который позволяет одновременно использовать несколько подключений. Поэтому определите свой объект за пределами вашего LoadStringFromEndpoint.

«по умолчанию HttpClient это самый простой способ, в котором вы можете посылать запросы. Один HttpClient может быть использован для отправки столько HTTP запросов, как вы хотите одновременно, так и во многих сценариях вы можете просто создать один HttpClient, а затем используйте это для всех ваших запросов ».

Больше info