views:

325

answers:

4

Hi

This is a question about best practices i guess but it applies directly to my current MT project.

I'm using WCF services to communicate with the server.

To do this i do the following:

services.MethodToCall(params);

and the asynch:

services.OnMethodToCallCompleted += delegate{
    //do stuff and ting
};

This can lead to issues if you're not careful in that variables defined within the scope of the asynch callback can sometimes be cleaned up by the gc and this can cause crashes.

So - I am making it a practice to declare these outside of the scope of the callback unless I am 100% sure they are not needed.

Now - when doing stuff and ting implies changing the ui - i wrap it all in an InvokeOnMainThread call. I guess wrapping everything in this would slow the main thread down and rubbish the point of having multi threads.

Even though I'm being careful about all this i am still getting crashes and I have no idea why!

I am certain it has something to do with threads, scope and all that.

Now - the only thing I can think of outside of updating the UI that may need to happen inside of InvokeOnMainThread is that I have a singleton 'Database' class. This is based on the version 5 code from this thread http://www.yoda.arachsys.com/csharp/singleton.html

So now if the service method returns data that needs to be added/updated to the Database class -I also wrap this inside an InvokeOnMainThread call.

Still getting random crashes.

So... My question is this:

I am new to thick client dev - I'm coming from a web dev perspective where we don't need to worry about threads so much :)

Aside from what I have mentioned -are there any other things I should be aware of?

Is the above stuff correct? Or am i miss-understanding something?

Cheers

w://

A: 

Wayne, can you give some more context, more code? in general what you're doing is fine, so it would be good to see a full sample. have you built a repro case?

bryan costanich
It turned out i was dismissing a modal view from within the context of the modal view: this.dismissmodalviewcontroller();Now this isn't normally a massive problem except that before doing this i was firing an event: ModalViewDismissing();On the cases where that event was being listened to - there was a problem. All good now :)
cvista
A: 

I'm working on an iPhone app with monotouch and have a similar issue with frequent random crashes to my simulator. I had scoured the internet for other examples of this but it doesn't look like there are too many people that have this problem (which leads me to believe I'm not doing something right).

Coming from a .NET background what I had on my project was dot notations on my namespaces and my project name and I read that, that was something I needed to do away with, I spent Monday cleaning up my namespaces and things started looking promising. Although when I hooked into web-services today, I got the same issue as Wayne.

This has caused countless hours of frustration. I'm really hoping there's an answer out there. I really hope that I'm doing something stupid with my code, at least that way I can go fix it.

Here's an example of an async call I'm doing:

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();

        var views = NSBundle.MainBundle.LoadNib ("SomeView", this, null);
        _view = new SomeView (views.ValueAt (0));
        _view.Initialize ();
        _view.SaveClicked += HandleSearchClicked;

        _waitingView = new Utility.PleaseWaitView ();
        _waitingView.Show ("Searching, please wait...");
        _waitingView.ResignFirstResponder ();

        _service.GetSomeSearchResultsAsync (_searchParams, HandleSearchResultsCompleted);
    }

    private void HandleSearchClicked (object sender, ObservableCollection<SearchResultModel> models)
    {
        // Since we are running on a separate thread, we can not access  
        // UIKit objects from here, so we need to invoke those on the  
        // main thread:  
        InvokeOnMainThread (delegate 
        {
            _waitingView.Hide ();
            if (models == null) 
            {
                Utility.ShowException ("Search Failed", "DOH!");
                return;
            }

            _source = new GenericTableViewSource<SearchViewCell, SearchResultModel> (_view.TableView, models);
            _source.RowAnimation = UITableViewRowAnimation.Fade;
            _source.RowSelect += HandleRowSelected;
            _source.TableViewCellAccessory = UITableViewCellAccessory.DisclosureIndicator;
            _view.TableView.Source = _source;
            _view.TableView.ReloadData ();
        });
    }

I really hope someone has a solution.

Thanks.

John

jmathews
i've not heard of the dot notation issue - it doesn't seem to affect me...
cvista
that code doesn't seem to suffer any of the code smell that mine had. You're not declaring anything in scope that can be gc'd when you still have ref. I'd be interested in hearing if you get to the bottom of this. These sorts of bugs are notoriously hard to get to the bottom of as the stack shows nothing.
cvista
I have found the MT IRC very very handy for things like this as well as SO :)
cvista
I'm not too familiar with MT IRC or SO. Are we talking about Internet Relay Chat? :)
jmathews
yeah - http://monotouch.net/Chat:)
cvista
A: 

I too am experiencing a similar issue with Webservices. The twist is that I have never had a crash in the simulator - only on multiple devices (iPads in this case).

I am am starting to wonder if it has something to do with the quality of the connection - the crashes happen way more often using 3G rather than WiFi. Further, the crashes are COMPLETELY random. And just to add further insult to injury is the fact that the app can crash 3 times in a row and then run for 30 minutes just fine (it refreshes from a WS every 15 seconds)...

I have been able to get some stack traces (deploy to the device from MT while running the iPhone Configuration Utility on the Console tab) but the crashes happen all over the place - not in just one spot. Although, it is ALWAYS after an update from the WS. The thing that sucks is that they are not trappable - try/catch blocks do nothing, at least in my case.

I could submit the stack traces to Novell if we think this might be a bug in MonoTouch. Not sure where to go from here - back to objective-c? Shudder.

jwpublic
there's no way i'm doing obj c :)
cvista
A: 

FYI, we got over this hump by keeping a reference to the original controller when the app finishes launching (in our case a navigation controller). The issue we were facing was that the GC was clearing up the controllers because it thought it was un-necessary because they were declared within the scope of the method.

I hope this answer helps someone else in the future.

Cheers.

jmathews
thanks for coming back with that - it was def a reference issue. Mine was a bit clearer once I understood what was going on.
cvista