This is my hobby and passion. :)
Friday, February 20, 2015
Wednesday, January 14, 2015
C# code for E-Gizmo's RFID using Observer Pattern
Here is a console application to demonstrate the E-Gizmo's RFID. The code is written in C# / .NET 4.5. This uses simple observer pattern with one subscriber. The code could still be extended to support many subscribers.
Saturday, August 2, 2014
Music: My version of Floyd Rose Tremolo Stopper for my Craftsman EG-95 guitar
Just now, I tried to create a Floyd Rose Tremolo stopper from another cheap floyd rose. I used the saddle/intonation screw and i turned out to be working pretty well. :) No vibrations nor any problems after the modifications. :)
![]() |
Labels:
crafstman,
EG-95,
floyd rose,
guitar,
tremolo blocker stopper
Sunday, July 27, 2014
.NET CF / Windows CE Threading
Lately, I was baffled by a problem in my current Windows CE/ Windows Mobile project. The scenario is quite simple:
It seems to me that the code is being executed again despite it is inside a lock construct. Normally, what I will do on a PC-based .NET application is to set the control's Enabled property to False, then issue an Application.DoEvents before enabling the property again. Doing this in .NET Compact Framework with a device that is not as fast a PC, gives an undesirable aesthetic effect. Our device's screen painting is quite slow and doing this method grays out the entire form then back to normal again.
Going back to topic and to illustrate my point:
I did an experiment using lock (See the function LockingUsingDotNetLock on the source code). If I press keys within 750msec, the textbox will display the same numbers! It must be incrementing! What happened? I would like to admit that I missed a crucial information regarding C# lock. Just yesterday, I researched more about it (Google, MSDN, StackOverflow.com) and found out that C# lock is re-entrant. It will block access to other threads but it can be acquired again and again by the same thread (Re-entrant Mutex).
Now I know the problem. What will be the solution? Here are the solutions that I could think of as of the moment:
- I have a Keydown event on my form.
- On the keydown event handler, I need to do some task which just takes around 500msec to complete.
- On that keydown event handler, I placed a C# lock construct to block the incoming keypresses (and with some Application.Doevents to pump the message queue).
- Then I did some destructive testing. The outcome: If I press a lot of key within the 500msec, the application throws an StackOverflowException.
- Next, I used the Monitor.TryEnter/Monitor.Exit so no blocking will occur. I did the same test. The result: StackOverflowException.
It seems to me that the code is being executed again despite it is inside a lock construct. Normally, what I will do on a PC-based .NET application is to set the control's Enabled property to False, then issue an Application.DoEvents before enabling the property again. Doing this in .NET Compact Framework with a device that is not as fast a PC, gives an undesirable aesthetic effect. Our device's screen painting is quite slow and doing this method grays out the entire form then back to normal again.
Going back to topic and to illustrate my point:
- I created a sample Windows Form Application. Source code
- There is a keydown event. This must display an incrementing number, have a delay of 750msec, increment the counter, then exit the handler.
- The expected behavior is to display incrementing number each time a key is pressed.
I did an experiment using lock (See the function LockingUsingDotNetLock on the source code). If I press keys within 750msec, the textbox will display the same numbers! It must be incrementing! What happened? I would like to admit that I missed a crucial information regarding C# lock. Just yesterday, I researched more about it (Google, MSDN, StackOverflow.com) and found out that C# lock is re-entrant. It will block access to other threads but it can be acquired again and again by the same thread (Re-entrant Mutex).
Now I know the problem. What will be the solution? Here are the solutions that I could think of as of the moment:
- Using ordinary volatile variable for the locking (See the function LockingUsingVolatileVariable on the source code). It is a very simple solution. If I press keys, only one key will register and the incrementing number will display correctly. Most of the time, this is the behavior that we need.
- Using lock, but this time, we spawn another thread inside the handler (See the function LockingUsingDotNetLockOnAnotherThread on the source code). If I press keys, the key's will queue up, and will display incrementing numbers with respect to the 750msec delay in the code.
- Using Monitor.TryEnter and spawn another thread inside the handler (See the function LockingUsingTryMonitorOnAnotherThread on the source code). This will have the same behavior with Solution #1.
Sunday, July 13, 2014
Chain Of Responsibility Design Pattern (Minus the repeated codes)
Last week, I studied Chain Of Responsibility Design Pattern. It was a good design pattern, but from the sample codes that I had seen, one common thing is that there are lots of duplicated codes. I would like to improve these and here are my main goals:
- As much as possible, eliminate or minimize the repeated codes.
- The concrete classes must not worry about the successor as much as possible and must not contain if else statements to call the successor's methods in case the caller can not perform the operation.
- If the additional logic statements for handling of next successor will be removed from the concrete classes, it will be easier to reuse those concrete classes.
I uploaded the code on my github. Link
- As much as possible, eliminate or minimize the repeated codes.
- The concrete classes must not worry about the successor as much as possible and must not contain if else statements to call the successor's methods in case the caller can not perform the operation.
- If the additional logic statements for handling of next successor will be removed from the concrete classes, it will be easier to reuse those concrete classes.
I uploaded the code on my github. Link
Sunday, June 15, 2014
Lessons Learned in Windows Mobile (Windows CE and .NET Compact Framework 2.0) Development Part 1
It has been months since I joined a company whose products revolve around Windows Mobile 5 and we are using .NET Compact Framework 2.0 and C# for the development. So far, the product is still far from over, but in agile sprint point of view, the product is getting better and better everytime we present it to the stakeholders at the end of sprint iterations. As the lead developer of the project, here are the things me and the team had learned so far:
- GUI toolkit. The best I had seen is Resco Mobile Toolkit. I had tried demo versions of different toolkit and this one stands out visually. In my initial assessment, Resco's UI Components are slow in terms of rendering. But I accidentally discovered that by issuing a Control's Refresh method, the rendering is accelerated. Plus, compared to a competitor toolkit, this has so many additional things (WebDav, Audio, Zip, etc). The license fee outweights the advantages. We are currently using this in our project.
- Protobuf-net. DotNET CF 2.0 doesn't provide binary serialization by default. I am currently using this heavily on my project. https://code.google.com/p/protobuf-net/
- Using SQL CE and .NET Datatables. One of my colleague insisted to create an SQL CE based database on the extracted data from 3 CSV files which is just a couple of size (around 350KB combined size). After the implementation, our system - which has a total of 64MB - got 32MB of free RAM and there is some performance hit when the database is being queried (SQL connection always open). We tried to open and close the connection, but a further performance hit was experienced although the memory consumption is much lower. I tried to use a memory-persisted Datatable and our system got 42MB of free RAM and no performance hit (queries using DataTable's select method). I did a further research and SQL CE takes around 8MB or more once it is instantiated and left open. I perceived that if the data is around byte or just kilobytes in size, it may be a good idea to just use in-memory Datatables. But if the database is very large, let's say in order of 100MB, it is not a good idea to use in-memory Datatables and stick with the file-based database instead. So as a lesson learned, we try to weigh things first and communicate with each other often especially if a sprint product backlog item is in design stage.
- Architecture. Whether we are a fan of MVC (Model View Controller) or MVP (Model View Presenter), there must always be a separation of concern between those things. After doing a trial run for the MVC and MVP architectures, I am currently sticking with MVP in Passive View. If one is not careful though, the Presenter tends to become a God object (which is one of the known problems of Mediator pattern). If we tend to solve it aggressively, we could end up having lots of classes and interfaces, and too many passing of interface parameters and in the end creating more confusion - which sometimes do more harm than good.
- Pinvoke. Pinvoker is a very good Visual Studio plug-in (and it is free!). http://www.pinvoker.com/Downloads.aspx
- Pinvoke with structure arrays. I had problems Pinvoking at structure with another structure array inside. Based from my research, there is no known work around for this and instead I created a Python script to generate elements for this problem.
Labels:
protobuf,
protobuf-net,
resco,
resco CRM,
SQL CE,
SQLCE,
windows CE,
windows mobile
Tuesday, March 11, 2014
Information Sharing: Fixing debugging problems: Win CE 5.0 device and VS2005 under .NET CF 2.0
This is a short one :)
I had debugging problem today and the fix is to simply install .NET Compact Framework 2.0 Service Pack:
http://www.microsoft.com/en-us/download/details.aspx?id=20943
:)
I had debugging problem today and the fix is to simply install .NET Compact Framework 2.0 Service Pack:
http://www.microsoft.com/en-us/download/details.aspx?id=20943
:)
Subscribe to:
Posts (Atom)