This is the first post and it was inspired by the question on SO. To better describe the problem, let’s make a very simple App which will have three TextBoxes:


Pic. 1 Overlook


The main task of our App is that it should update all three TextBoxes, depending on the user input. So in the code behind we will create an event handler and subscribe it to TextBox.TextChanged event (in this simple example I’ll just put the text informing which TextBox was changed):

As you can see, I’ve subscribed Box_ChangedOne to all three TextBoxes  – let’s update everything right after one of them changes (why not?). Here comes the first problem, just after we focus on any control and try to put text – our App hangs. Aha – longer look at the code and it turns out that we are in an infinite loop – our event fires another one (cause it is changing TextBox.Text) and so on.  So we will improve the event handler with a flag which will inform if the change was invoked by user or from the code:

Looks great, so we should test it. Oops, the program hangs – what is wrong? The solution comes with the MSDN: The TextChanged event is asynchronous. Our simple code is racy, and line  dontChangeFlag = false; is fired before the events – so we are again in an infinite loop. So why not delay a little our process and wait for other events to finish?

This time we get what we wanted – our flag is working. So far so good – but how to predict how long will it take the phone to finish the events? The answer is – we can’t and don’t do it – let the event informs when it is finished. For this purpose I’ll use a SemaphoreSlim class. And here we will also improve our code (to show the next issue) – our first TextBox will be set up with the entered text:

Our semaphore should wait until it is released, and it does so, but if we just change the text in the FirstBox then we will see that something is worng – there is no change in other TextBoxes. Quick debug shows that the semaphore waits to be released – what is wrong? Again qucik look at MSDN shows what is going on – If the Text property is set to the same string as the content in the TextBox, the event is not raised. The simpliest way will be to check if the event is going to run:

Finally our code is working as it should.

One may ask – what is the purpose of the slider in the picture? This is a simple test showing that not every event is run asynchronous – if we write a similar method like above, but for Slider’s change:

and set up breakpoints at lines 3 and 9, then we will see in debug mode that everything works synchronously.

Conclusion: Even if think that you write your code as synchronous, some events/methods can be run as asynchronous, so it’s worth to check them in the documentation.

Complete working example you can download from here.

Each post's copyright held by the original author. All rights reserved.