Freigeben über


Real World WCF on Windows Phone 7

I have already covered using WCF from Windows Phone 7 with my quick walk-through , but now, some months later, I have now shipped an application that uses it, and learned a few things on the way that help get a connection to the local WCF host reliably.

Name Resolution

My app requires connection to a WCF service hosted on a PC on the user's home network, so it asks the user for the name of the PC then connects. What could possibly go wrong? Er quite a lot actually. Although this worked well for me, it turns out it doesn't work well for many paying customers, who have to specify the actual IP address of the PC instead of its name. Further digging revealed why I was in the minority: my Actiontec router (supplied by Verizon for my Fios connection) actually includes a real-life DNS Server. It is auto-configuring, and fills itself based on broacasts on the local network, so I never realized it even existed. Once I turned it off, I became much more like my customers, and my phone app would never connect to my server by name.

After asking around at work I found that WP7, when on wi-fi, will use DNS and WINS to find network endpoints by name, but that's all. As few home networks run DNS or WINS servers that proves to be rather a problem for apps like mine. On most home networks name resolution is done on PCs by NetBIOS or UPNP, but WP7 has neither. As third party phone apps cannot get to sockets then there is no other way to resolve names.

Getting A Connection After Waking

The wi-fi connection is dumped when the screen turns off, so when you wake a WP7 device the radio has to come up, find your wi-fi router and have a chat. This takes time, and the time seems to vary by device, by network, and by the phase of the moon. To try and make things a little more reliable my app does the following, in an effort to get the wi-fi connection up and my WCF connection going as promptly as possible:

Try the WCF connection

if it fails then

    call NetworkInterface.NetworkInterfaceType (and ignore the result)

    set a timer

        Try the WCF connection

        if it works then exit and do real work

    until the timer hits 30 seconds

then if still nothing, ask the user to retry. This results in a 97% success rate in attaching in to the WCF service in 30 seconds, at least on my network and devices. YMMV. (By "Try the WCF connection" I mean make a call through the service proxy).

Random Exceptions during Exit

Through my LittleWatson diagnostics I would occasionally get crashes during app exit that would never repro with a debugger attached. The callstack was always the same, vis:

at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)
at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStreamAsyncResult.OnGetRequestStream(IAsyncResult result)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClass6.<InvokeGetRequestStreamCallback>b__4(Object state2)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()

I never succeeded in stopping this from happening, and could not catch the exception as it is on someone else's thread, so I modified my LittleWatson to ignore this specific callstack. I can only speculate that when an async call comes in at the wrong point during process shutdown, something bad happens. (Others have reported a similar stack on vanilla http requests as well).

I hope these hints help you in your WCF endeavors. Of course if your WCF service is on the actual internet none of this applies (except the random exception) as DNS to live internet sites and wi-fi wake-up is not a problem.

Comments

  • Anonymous
    July 13, 2011
    Andy, I'm seeing the same random crash around calls made to our WCF service. I have no idea what's happening because it happens here or there and never really on the same call. But it makes all of my WCF service calls fail until the phone is rebooted (as in make the phone say 'goodbye' and start up again). It's intermittent and never happens under the debugger, just like you described. Did you ever get to the bottom of this issue? If a single call fails that's one thing, but I hate to have to tell my customers to reboot thier phones just to use our app. I know you posted this a while back, but I'm hoping you can shed some light. TIA.

  • Anonymous
    July 25, 2011
    Sorry I have no update for you WG. As I modified my LittleWatson code to ignore this specific exception I never see it "in the wild", plus for me its not as bad: I don't need to reboot the phone to get it to work again.