1

I'm using a LoadingView (custom UIAlertView with a UIActivityIndicatorView) to display different status. Here is the LoadingView code:

public class LoadingView : UIAlertView
{
    private UIActivityIndicatorView _activityView; 

    public void Show (string title_)
    { 
        Title = title_;

        _activityView = new UIActivityIndicatorView (UIActivityIndicatorViewStyle.WhiteLarge); 
        _activityView.Frame = new System.Drawing.RectangleF (122, 50, 40, 40); 

        AddSubview (_activityView); 

        InvokeOnMainThread (delegate() { 
            _activityView.StartAnimating (); 
        });

        UIApplication.SharedApplication.NetworkActivityIndicatorVisible = true; 

        Show ();
    }

    public void SetTitle (string title_)
    {
        Title = title_;
    }

    public void Hide ()
    { 
        UIApplication.SharedApplication.NetworkActivityIndicatorVisible = false; 
        DismissWithClickedButtonIndex (0, true);
    }
}

I'm also using geolocalisation. For that, the user needs a network connection, carrier data or wifi network. So, my app' needs to verify networks are available.

So, I add the Reachability class. I use the InternetConnectionStatus method:

public static NetworkStatus InternetConnectionStatus ()
{
    NetworkReachabilityFlags flags;
    bool defaultNetworkAvailable = IsNetworkAvailable (out flags);

    if (defaultNetworkAvailable) {
        if ((flags & NetworkReachabilityFlags.IsDirect) != 0) {
            return NetworkStatus.NotReachable;
        }
    } else if ((flags & NetworkReachabilityFlags.IsWWAN) != 0) {
        return NetworkStatus.ReachableViaCarrierDataNetwork;
    } else if (flags == 0) {
        return NetworkStatus.NotReachable;
    }
    return NetworkStatus.ReachableViaWiFiNetwork;
}

And I test it that way:

    partial void BtnLocationClick()
    {
        loading = new LoadingView();
        loading.Show("Looking for network");
        Console.WriteLine("Looking for network");
        if (Reachability.InternetConnectionStatus() != NetworkStatus.NotReachable)
        {
            loading.SetTitle("Network found");
            loading.Hide();
            // code here
        }
        else
        {
            loading.Hide();
            UIAlertView alert = new UIAlertView("Error", 
                                                "No network", 
                                                null, "Retour", null);
            alert.Show();
        }
    }

At the end, the network is quickly found (thanks to Console in InternetConnectionStatus method), but the LoadingView, declared before network detection and supposed to be shown is frozen.

When there is no network at all (no data and no wifi), it's perfect. It displays correctly. But when I've some network, it freezes. And then, after a long time, I can see "Network found" and things move on correctly.

I don't understand at all what's happening. Do you have any idea ?

Thanks in advance for the help you can provide.

Nate B.
  • 942
  • 11
  • 31

1 Answers1

2

You are doing this work and blocking the UI thread.

Let's say you did this:

loading.Show();
Thread.Sleep(1000);
loading.Hide();

You would never see the loading, since the UI thread is blocked and unable to render your loading popup.

You will have to use the .Net threading classes to do something like this:

loading.Show();
ThreadPool.QueueUserWorkItem(_ =>
{
   //Do your long running operation here

   BeginInvokeOnMainThread(() => loading.Hide());
});

The BeginInvoke part is very important. You cannot interact with the UI from a background thread, this invokes your code back on the main thread.

jonathanpeppers
  • 26,115
  • 21
  • 99
  • 182
  • It seems that you are completely right. [Here](http://stackoverflow.com/questions/11829960/monotouch-test-if-remote-device-is-found-on-local-network), Poupou has the same point. I tried your way, and it does not work. It's certainly my bad, I've never worked with threads. May you give me some head points ? – Nate B. Aug 17 '12 at 09:42
  • Post your threading code you are having problems with in the question (or better yet open a new question). – jonathanpeppers Aug 17 '12 at 12:14