简体   繁体   English

没有互联网时Windows应用商店应用崩溃

[英]Windows store app crashes when no internet

I am creating my first windows store app and i have several web service calls during startup and also periodically through the app. 我正在创建我的第一个Windows Store应用程序,并且在启动期间以及通过该应用程序定期进行几次Web服务调用。 However I have noticed that my app will ot start/crashes or just closes down when I don't have internet access because of the web serivice calls. 但是我注意到,由于网络服务电话而无法访问互联网时,我的应用程序将无法启动/崩溃或关闭。 I want my app to start up in normal way with some initial data and seem normal even when there is no internet access. 我希望我的应用以一些初始数据以正常方式启动,即使没有互联网访问,也看起来很正常。 The data I get from webservice are mostly weather data that I show in various textboxes and graphs. 我从网络服务获得的数据大部分是我在各种文本框和图表中显示的天气数据。

The code below shows the webservice calls in my extended splash screen. 下面的代码在我的扩展初始屏幕中显示了Web服务调用。

public sealed partial class ExtendedSplashScreen : Page
{

//parameterItem max1DayAgo = new parameterItem();
//parameterItem min1DayAgo = new parameterItem();


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

/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.  The Parameter
/// property is typically used to configure the page.</param>
protected override async void OnNavigatedTo(NavigationEventArgs e)
{

    string[] periodSelector = { "1DayAgo", "1WeekAgo", "1MonthAgo" };
    string[] modeSelector = { "max", "min" };
    string[] parameterSelector = { "umtTemp1", "umtWindSpeed", "umtAdjBaromPress", "umtRainRate" };


    //Create a webservice object
    ServiceReference.WebServiceSoapClient webServiceObj = new ServiceReference.WebServiceSoapClient();
    //First we create an object that holds max data for yesterday
    var getMax1DayAgoObj = await webServiceObj.GetSelectedMaxMinDataAsync(parameterSelector, periodSelector[0], modeSelector[0]);

    //create an object that holds min data for yesterday

    var getMin1DayAgoObj = await webServiceObj.GetSelectedMaxMinDataAsync(parameterSelector, periodSelector[0], modeSelector[1]);
    //Save arrayOfValue and arrayOfUnit to a parameterItem object. these objects are created during startup
    // and the can be accessed and updated by all methods in this page later we will see that maxMinButton_Click method
    //for the maxMinButton will use these data

    //create an object that holds max data for last week
    var getMax1WekAgoObj = await webServiceObj.GetSelectedMaxMinDataAsync(parameterSelector, periodSelector[1], modeSelector[0]);
    //create an object that holds min data for last week
    var getMin1WekAgoObj = await webServiceObj.GetSelectedMaxMinDataAsync(parameterSelector, periodSelector[1], modeSelector[1]);
    //create an object that holds max data for last month
    var getMax1MonthAgoObj = await webServiceObj.GetSelectedMaxMinDataAsync(parameterSelector, periodSelector[2], modeSelector[0]);
    //create an object that holds min data for last month
    var getMin1MonthAgoObj = await webServiceObj.GetSelectedMaxMinDataAsync(parameterSelector, periodSelector[2], modeSelector[1]);


    (App.Current as App).max1DayAgo.arrayOfValue = getMax1DayAgoObj.arrayOfValue;
    (App.Current as App).max1DayAgo.arrayOfUnit = getMax1DayAgoObj.arrayOfUnit;

    (App.Current as App).min1DayAgo.arrayOfValue = getMin1DayAgoObj.arrayOfValue;
    (App.Current as App).min1DayAgo.arrayOfUnit = getMin1DayAgoObj.arrayOfUnit;


    (App.Current as App).max1WeekAgo.arrayOfValue = getMax1WekAgoObj.arrayOfValue;
    (App.Current as App).max1WeekAgo.arrayOfUnit = getMax1WekAgoObj.arrayOfUnit;

    (App.Current as App).min1WeekAgo.arrayOfValue = getMin1WekAgoObj.arrayOfValue;
    (App.Current as App).min1WeekAgo.arrayOfUnit = getMin1WekAgoObj.arrayOfUnit;

    (App.Current as App).max1MonthAgo.arrayOfValue = getMax1MonthAgoObj.arrayOfValue;
    (App.Current as App).max1MonthAgo.arrayOfUnit = getMax1MonthAgoObj.arrayOfUnit;

    (App.Current as App).min1MonthAgo.arrayOfValue = getMin1MonthAgoObj.arrayOfValue;
    (App.Current as App).min1MonthAgo.arrayOfUnit = getMin1MonthAgoObj.arrayOfUnit;


    string[] startupData = new string[13];


    startupData[0] = " " + (App.Current as App).max1DayAgo.arrayOfValue[0] + " " + (App.Current as App).max1DayAgo.arrayOfUnit[0]; //    maxTemp 
    startupData[1] = " " + (App.Current as App).max1DayAgo.arrayOfValue[1] + " " + (App.Current as App).max1DayAgo.arrayOfUnit[1]; //    maxWindSped 
    startupData[2] = " " + (App.Current as App).max1DayAgo.arrayOfValue[2] + " " + (App.Current as App).max1DayAgo.arrayOfUnit[2]; //    maxAirPressure 
    startupData[3] = " " + (App.Current as App).max1DayAgo.arrayOfValue[3] + " " + (App.Current as App).max1DayAgo.arrayOfUnit[3];//     maxRainfall

    startupData[4] = " " + (App.Current as App).min1DayAgo.arrayOfValue[0] + " " + (App.Current as App).min1DayAgo.arrayOfUnit[0]; //    minTemp 
    startupData[5] = " " + (App.Current as App).min1DayAgo.arrayOfValue[1] + " " + (App.Current as App).min1DayAgo.arrayOfUnit[1];//     minWindSped 
    startupData[6] = " " + (App.Current as App).min1DayAgo.arrayOfValue[2] + " " + (App.Current as App).min1DayAgo.arrayOfUnit[2];//     minAirPressure  
    startupData[7] = " " + (App.Current as App).min1DayAgo.arrayOfValue[3] + " " + (App.Current as App).min1DayAgo.arrayOfUnit[3];//     minRainfall



    // Main fields
    // ServiceReference.WebServiceSoapClient webServiceObj = new ServiceReference.WebServiceSoapClient();
    var getLatestTempObj = await webServiceObj.GetLatestDataAsync("umtTemp1");
    var getLatestWindObj = await webServiceObj.GetLatestDataAsync("umtWindSpeed");
    var getLatestwindDirObj = await webServiceObj.GetLatestDataAsync("umtAdjWinDir");
    var getLatestairPressureObj = await webServiceObj.GetLatestDataAsync("umtAdjBaromPress");

    startupData[8] = " " + getLatestTempObj.Value + " " + getLatestTempObj.Unit;//temperatureMainTxtBlock.Text
    startupData[9] = " " + getLatestWindObj.Value + " " + getLatestWindObj.Unit;//temperatureMainTxtBlock.Text

    startupData[10] = "" + getLatestwindDirObj.Value; //temperatureMainTxtBlock.Text

    startupData[11] = " " + getLatestairPressureObj.Value + " " + getLatestairPressureObj.Unit;//temperatureMainTxtBlock.Text

    startupData[12] = "Last update: " + getLatestwindDirObj.Timestamp;//temperatureMainTxtBlock.Text
    //save the startup data to the global variables
    (App.Current as App).NavigateData = startupData;



    this.Frame.SetNavigationState(e.Parameter as string);
    this.Frame.Navigate(typeof(MainPage));
}
}

You need to implement some exception handling around this line: ServiceReference.WebServiceSoapClient webServiceObj = new ServiceReference.WebServiceSoapClient(); 您需要围绕这一行实施一些异常处理: ServiceReference.WebServiceSoapClient webServiceObj = new ServiceReference.WebServiceSoapClient();

and implement a fallback that will work in off-line mode, ie retrieve data from a cache. 并实施可在离线模式下运行的后备广告,即从缓存中检索数据。

You can use NetworkStatusChanged event in App.xaml.cs and then you can declare one static variable and use it to check whether Internet is available or not. 您可以在App.xaml.cs使用NetworkStatusChanged事件,然后可以声明一个静态变量,并使用它检查Internet是否可用。 If Internet is available do your desired operation otherwise show error message. 如果Internet可用,请执行所需的操作,否则显示错误消息。

public static bool IsInternetAvailable;

void NetworkInformation_NetworkStatusChanged(object sender)
{
    if (NetworkInformation.GetInternetConnectionProfile() != null)
        App.IsInternetAvailable = true;
    else
        App.IsInternetAvailable = false;
}

Always use try catch blocks, when you have probability of exception. 如果您有例外的可能性,请始终使用try catch块。

An approach we have in some of our team based apps is prior to any call to return data of the net, the network status is checked. 我们在某些基于团队的应用程序中采用的一种方法是在调用返回网络数据之前进行任何检查,然后检查网络状态。 Example: 例:


async Task RefreshFromWeb(...)
{
    if (!App.HasInternetAccess)
    {
        await new Windows.UI.Popups.MessageDialog(Strings.NoInternetWarning).ShowAsync();
        return;
    }

    //attempt access here
}

public static bool HasInternetAccess
{
    get
    {
        var profile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
        if (profile == null)
            return false;
        return profile.GetNetworkConnectivityLevel() == 
               Windows.Networking.Connectivity.NetworkConnectivityLevel.InternetAccess;
    }
}

We also took another approach at times which was very similar but uses await and returns true or false (the same could easily be done above, that approach above just gives the dialog) 我们有时也采用了另一种方法,该方法非常相似,但使用了await并返回true或false(上面可以轻松完成,上面的方法只是提供对话框)

public static async System.Threading.Tasks.Task HasInternet()
{
    var profile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
    var hasNetAccess = profile != null;
    if (!hasNetAccess)
        await new Windows.UI.Popups.MessageDialog(
            content: InfoHub.AppHubViewModel.Strings.NoInternetWarning,
            title: InfoHub.AppHubViewModel.Strings.NoInternetWarning).ShowAsync();
    return hasNetAccess;
}

async void YourControlEvent_Click(object sender, ItemClickEventArgs e)
{
    //if net access, do your stuff, otherwise ignore for now
    if (await IsInternet())
    {
        //do net calls here
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM