Windows store应用程序在没有互联网的情况下会崩溃。

时间:2023-01-19 14:19:34

I am creating my first windows store app and i have several web service calls during startup and also periodically through the app. 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.

我正在创建我的第一个windows store应用程序,并且在启动期间我有几个web服务调用,而且还会定期通过应用程序。但是我注意到,由于网络的串行接口调用,我的应用程序无法启动/崩溃或者关闭。我想让我的应用程序以正常的方式启动一些初始数据,即使在没有互联网接入的情况下也是正常的。我从webservice获得的数据主要是我在各种文本框和图表中显示的天气数据。

The code below shows the webservice calls in my extended splash screen.

下面的代码显示了在我的扩展启动屏幕上的webservice调用。

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));
}
}

3 个解决方案

#1


0  

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)

我们还采用了另一种方法,这种方法非常类似,但是使用等待并返回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
    }
}

#2


0  

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, i.e. retrieve data from a cache.

并实现一个将在离线模式下工作的回退,即从缓存中检索数据。

#3


0  

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. If Internet is available do your desired operation otherwise show error message.

您可以在App.xaml中使用NetworkStatusChanged事件。然后您可以声明一个静态变量,并使用它来检查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块。

#1


0  

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)

我们还采用了另一种方法,这种方法非常类似,但是使用等待并返回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
    }
}

#2


0  

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, i.e. retrieve data from a cache.

并实现一个将在离线模式下工作的回退,即从缓存中检索数据。

#3


0  

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. If Internet is available do your desired operation otherwise show error message.

您可以在App.xaml中使用NetworkStatusChanged事件。然后您可以声明一个静态变量,并使用它来检查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块。