January 2005 - Posts

I was having this discussion with Vivek about Asynchronous Execution and circular reference and I realized that whenever you have a discussion with someone, you should try to contradict him in a positive manner. On one hand I was contradicting Vivek on the subject. He said that I should be using Wait() Notify() in the application and I said that it is not applicable. On the other hand, I was having the same discussion with my team telling them that we should be using Wait() Notify() and they were against me.

I understand the requirement of the application and the constraints of the environment more than Vivek because I am in the project and he is not. But this gives him a third person perspective which me and my team mates do not have. Probably My team is going to win the discussion eventually. But in the process, I am going to learn so many different things. All I am trying to do is analyzing an alternative solution, which might / could have been much simpler if it were feasible.

But all this was possible only because I contradicted with everyone. With Vivek and with my team mates. Once on this side of the debate and once on that.

Telling you about a problem that we faced today. We are writing a handheld application for Windows CE. The application communicates with a Java based base station, using a web service. We call a web service on the base station that sends back a string of commands separated by tildes. These commands contain information regarding the UI and the behavior of the application. Like there is a Message command which means a label control has to be rendered on the form and there is an accept command that means a textbox has to be rendered on the form. These commands contain information regarding the placing of the control, the behavior, the contents, etc.

Now the design was something like this. There is a main controller that controls the entire flow of the application. It executes all the commands one by one. There is a command parser which takes this string of commands and parses it into different command objects. There is a GUI Controller that renders these commands into windows form controls. So the typical thing here is that the application is partially sequential and partially event driven. The commands have to be executed in the sequence that we receive them. But if we encounter an accept command (which means a textbox has to be rendered on the form!), then the application switches to event driven mode, where we have to wait for the user input.

So the main controller has a start() method that triggers the entire flow of events. This method calls a host of methods and initializes a host of objects by calling their constructors etc. until an accept (textbox) command is encountered. Once this is done, the control returns. Now when the user provides its input to the textbox and presses enter, we have written an event handler, that stores the response of the user in the accept command, and then calls the next command. After that the command execution sequence is resumed.

There is also an end and a terminate command. Now the end command means the end of batch and the terminate means the application is closed. After the end of one batch, the data taken from the user is sent to the host. Which means a web service is called. The web service on the base station sends the data to the back end main frame system and sends the next batch of commands. For this process, we have a SendMessageToBS() method. This method is called from the Execute() method of the End Command object. This method calls the Start() method of the Main controller and this starts a loop.

Problem: we enter a loop which never ends. In a way what we were doing was we were calling the SendMessageToBS() method from Start() (of course there were a host of other things that we were doing in between) and then we are calling Start() from SendMessageToBS(). So we are not returning the control to where it started from at all.

This was increasing the stack size and there were memory issues because we were writing for a handheld device.

The thing is we discovered this problem late in the development process and for once me, my team mate and my team lead were pretty tense about the situation. What are we going to do. Are we going to have to scrap the entire code and go back to formula? How much refactoring is required after all?

So we went back to the whiteboard. And started with drawing a sequence diagram of the entire sequence of events. The solution was quite easy actually. We just needed to put in some thought and it is in a way amazing that we didn’t think of this circular reference back during the design phase.

The solution: We would create a custom event (delegates and shit!). write an event handler for this event which would just call the Start() method of the Main controller, triggering the entire sequence of commands. Now we call the start() method from the main application on load. Once the entire sequence is over, and we send the data, we just raise this event and return. Our initial problem was that the control was not returning to its point of origin. This was increasing the size of the stack. This problem is solved now. The control returns to its origin freeing all the occupied resources and a new sequence of processing is started.

It was fun. Problems like these at times really keep you going. This is a problem that is really worth spending time on. And what I am really satisfied with is that we didn’t have to spend a lot of time on finding a solution of this problem. It is the simple problems that I am really worried about. I think getting a good book of puzzles by authors like Shakuntala Devi and solving those problems would really help me in thinking fast and solving easy problems.

There is this controls array, a property of the System.Windows.Forms.Form. All the controls that are in the form, are listed in the controls array and if you want to remove a particular control from the form, you just call the RemoveAt() method of the control array which will remove the control from the specified index.

Now I had a specific requirement where I was supposed to remove all the textboxes from the control array. So I ran a loop. If the control is a textbox, I would remove it else move on. But every time I call remove(), the indexes would be shuffled. So in case there are adjacent textboxes, I would miss some if I keep going in a sequence.

First thing that comes into my mind. Keep searching for textboxes in a loop until we are sure that there are no textboxes in the collection. For that every time you remove a textboxes, start the loop from zero by resetting the index to -1 (funny...!)

Second thing that comes into my mind. No need to go searching from 0 all you have to do is reduce your index by one and start searching again.

Then I realize I am going in the wrong direction. So I must think of a way where even if the index is being shuffled, it should not affect the sequence of operations.

So I loop through it backwards. Remove the last control first, and then come back. That would not disturb my previous indexes, and I would be able to remove them most efficiently.

Anyone can get to a simple solution like this. The important thing is how much time does he take?

There was this problem that I was working on which I think was pretty interesting. We are writing an application for a handheld device. Now there are textboxes in the application which we have to deal with. Now if the user wants to navigate from one textbox to its previous textbox, he has to press a combination of keys. Like for example Shift+S or Shift+B. this combination could be anything and is taken from a configuration file. Now the issue was this. Suppose it is Shift+S, when the user, used the combination, there was a capitalized S being printed in the textbox before the focus moved into the previous textbox.

 

Now we were handling the Key Up event of the textbox where we wrote code that would move the focus to the previous control. So when we did an e.Handled=true in the key up event, it didn’t work because the rendering was already done. The deadlines were short and everyone was in frenzy. So we didn’t really realize immediately what happened. So we left the issue open for a day.

 

Once we were done with things that were immediate in hand, I started looking into it. The solution was so simple, that I couldn’t believe it didn’t strike to me yesterday. When I started looking into it, I realized that the rendering was being done in the key press event. So if I want to disable it, I have to do an e.Handled=true in the key press event. There are two more events that I was looking into and that is Key up and Key down. Now Key down would be useful if you want to find the modifier keys. Key press event didn’t give me the modifier keys. So I couldn’t have found out whether the shift key is being pressed in the key press event. I would have to use the key down event for that.

 

So I was in a situation where key down would tell me whether the shift was pressed or not and key press would allow me to disable the rendering. So I declared a static Boolean variable IsShiftPressed which would be reset in all the 3 events. Key down, key up and key press. Once when the Shift Key is pressed, it would be set to true in the key down event. And in the key up event it would be set to false since now it is not in the state of being pressed. In the key press event I would check if the value of IsShiftPressed is true or not if it is then I would disable the rendering by doing a e.Handled=true.

 

The solution was that simple. When it didn’t come to me, I was getting all vague ideas like letting the system write the letter in the textbox and the clearing it, storing the whole value in a variable and then clearing it and then resetting the textbox.text property, etc. it is all a matter of perspective. So as they say, when things start getting heavy, you should cool down, but in a real life scenario, the exact opposite usually happens. And you become unable to see a solution that is staring right at your face.

More Posts