Cross-Threaded Calls in .NET!

Now-a-days everybody has a Multi-core environment and you are required to code threads and/or multiple processes to be scalable and fully utilize the current hardware systems. And yes, it also proves that you are a good coder and are keeping up and committed to development of multi-threaded, multi-core applications. Now, now, I am talking a bit silly since threading is a concept existing since the dawn of computing. It was pretty much explicit and you can feel the power when you code in C or C++. But when it comes to high level frameworks and languages like .NET, C#, VB.NET, etc. the simplicity of using threads might become a big problem and lead to no understanding of how things actually operate. Of course execution context is something to learn about and a good programmer should always be aware of what execution context his/her thread/process is executing in otherwise he/she would find himself/herself in a lot of problems related to thread synchronization, deadlocks, etc.

I am still pretty new to C# and decided to use threads in MultiDoc2HTML v0.2 (v0.1 is available on Multiple HTMLs into a Single Document – MultiDoc2HTML v0.1). The logic as explained in other articles on the blog is quite serial and repetitive i.e. one cannot use multiple threads to do the job since each and every operation has to be done one after the other. In short, it is a batch operation which is not a direct candidate for multi-threading. But still there are ways to attack the problem and use threads especially for this particular logic. Not to deviate from the topic at hand, I will write about that in some other post.

For the time being, I wanted to do the batch execution in a separate thread (I could have used background thread for that but I think thread is more clean then background thread). Anyways, I will create one more version with background thread later on. But for the time being, I created a separate worker thread to do the batch processing and the main thread keeps updating the UI properly i.e. show the progress bar. It uses a timer tick event to do it i.e. Progress bar is not a visual indication of amount of work done/left. It is just there to tell the user that the worker thread is doing its work. The worker thread does the batch execution and generates an event to notify the main thread when all the processing is done. I would like to put the progress bar to the maximum value to be esthetically correct since having it midway would not be a justifiable execution complete message.

Now I thought that the event would post a message in the application message queue and the WNDPROC will call the proper event handler. But it does not seem to be the case since the event handler which is in the main thread gets called from the worker thread’s context. It sounds strange but that is the way events are working in C# i.e. the execution context of the event handler is same as the execution context in which the event is raised. Internally it might be handled as a direct call instead of PostMessage() that we c++/Win32 people normally expect.

Anyways, one of the problem with these kind of cross-threaded calls is that one cannot update the UI controls in such callbacks. They are deemed unsafe and they are unsafe since the execution contexts are totally different. The .NET compiler/interpreter fortunately helps us to identify such calls. The solution is to check for property InvokeRequired for the control and if it is true, do a self delegate and delegate our call. The next time, InvokeRequired will be false and the call will be made from the main thread’s context since we had delegated it previously. Its a bit twisted but thats how it is supposed to work. I would especially do an InvokeRequired check in events since they are more or less the mechanisms that I use for inter thread communication.

And remember that you need to do this for all the individual controls and it can become quite cumbersome. Fortunately templates are to the rescue. I found a nice snippet on the internet which allows us to make cross-threaded calls without creating delegates explicitly and checking for InvokeRequired on every control function/property. The CrossThreadUtility class is static with a static InvokeControlAction method as shown below.

    public static class CrossThreadUtility
    {
        public static void InvokeControlAction(t cont, Action action) where t : Control
        {
            if (cont.InvokeRequired)
            { 
                cont.Invoke(new Action>(InvokeControlAction), new object[] { cont, action }); 
            }
            else
            { 
                action(cont); 
            }
        }
    }

To use it in your code, just call the InvokeAction in the following manner. I wanted to change the progress bar value to maximum.

CrossThreadUtility.InvokeControlAction<ProgressBar>(prgBarProgress, tempPrgBar => tempPrgBar.Value = tempPrgBar.Maximum);

The first template parameter is the type of control. In my case it is System.Windows.Forms.ProgressBar, prgBarProgress is my variable associated with that control, tempPrgBar is a temporary progressBar variable created for delegating the cross threaded call. The statement after => is that function that I to call or the property that I want to set. And all these works like a charm.

Use it and forget the headaches about cross-threaded calls and delegates. Have fun computing…

Multiple HTMLs into a Single Document – MultiDoc2HTML v0.1

I was developing a program which allows me to take a bunch of HTML files and put it into a single document. These files need to be put in as rendered in IE and the HTML code tags should not be visible. Still all the links, etc. should be along in the document so generated. Manual way to do it would be to open the HTML files one by one in Internet Explorer or any other browser, press CTRL+A, then CTRL+C, open the word document, go to End of File (EOF) and then press CTRL+V. One of the questions is the use case. Why would I need to do something like this?

 

We are all aware of e-books in CHM (Complied HTML format). I have loads of them. And sometimes, the TOC (Table of Contents) gets corrupt due to one or other reason and I cannot navigate around. The other thing is that if I want to print, I cannot print all of the topics in the ebook. I need to select one by one and I don’t know if it is only on my PC, that I cannot get them to print properly. Most of the time, the output is blank pages. Also you loose the flexibility of converting to another favorable format such as PDF, etc. Hence I generally de-compile the HTML using Microsoft HTML workshop and then make a doc out of it. If you have 5 HTML pages to deal with, it is okay to do so manually. And I found it very boring with 5 anyways.

 

Read more about it, get the binaries and source code in the forum link: http://www.naresh.se/phpBB/viewtopic.php?f=17&t=11. The same link will also talk more on the implementation details about pipes, events, COM interfaces, Wrappers, etc. once I dissect the code and start with explanations interested people to follow. It also uses the Full Duplex anonymous pipes as explained in the post: http://www.naresh.se/2009/09/16/anonymous-pipes-in-windows/

 

Ahhh… and one more thing before I close the post. You might be wondering as to why I am writing code for doing the shit, when I can open word document, click on Insert File and select all the HTML files and it just works as my code does. Well, it does, but try doing it with 100 files and Word would simply not be able to do it. At least it didn’t work on my machine and I don’t know if my machines Word installation is fucked up or if Word seriously cannot do it.

 

Cheers & have fun computing…

Anonymous Pipes in Windows!

Recently I had been working on a program to get a set of HTML files rendered in IE and then copy the contents from the IE window to a word document. I wanted to do this in VC++ since it provides very easy access to COM objects like IE, Word, etc. and I have also used it in the past to build BHOs (Browser Helper Objects) and like. VB also supports COM but usually has pretty complex procedures to do minor things. And I forgot about .NET and the wrapper libraries around COM objects which provides very easy access. If I want to do something like that I would better use C# instead. But as it goes, I started coding in VC++. The basic logic of the code is as follows:
– Ask the user the select a directory with all the HTML files that you need to put in word
– Ask the user for the word document to which the content will be put to
– Open the specified Word document and keep a handle to the application or document object
– Open an IE Window (Invisible)
– Render the HTML file in the invisible IE Window
– Select all the contents from the IE Window and Copy it to the Windows Clipboard
– and paste the clipboard contents and save the file
– Repeat the step from rendering the HTML file onwards until all the files content are in the word doc
– Save and close the word file and the application object and release all the COM instances
Sounds a bit complicated and it is since I later realized that you can use the Word Objects InsertHTMLFile() directly instead of using Windows Clipboard which is unreliable as well as open to other rogue applications which can hang this particular application. But since I want to use it for my own purposes and not productize it, I am okay with the said approach. Again, I had almost finished my whole application until I found out that information. Wish Microsoft/Bing/Google could relate such information without me explicitly asking for it.
Anyways, so after almost writing 60% of the application, I realized that my Office 2003 installation is fucked up and that the COM Wrapper classes generated in VC++ after adding an ActiveX component for Word gives a lot of compilation errors. I tried a lot of different things including using #imports of the GUID for VBE and Word with the no_implementation keyword. None worked since removal of compilation errors would turn into runtime errors when I tried to call them in the code.
Anyways, then I decided to use a C# helper program to achieve the feat. And I decided to use Anonymous Pipes to communicate between my main VC++ app and the client C# app. I didn’t want my pipes to be used by any other program as well as wanted to limit the lifetime of the handles in case any of the apps crash. Hence I used anonymous pipes instead of named pipes. And since anonymous pipe is a half-duplex/suplex pipe, I have created easy classes to both implement a Full Duplex or half-duplex anonymous pipes depending on the needs. In most cases, one would require Full Duplex pipes to ideally do a proper communication.
Download the code from http://www.naresh.se/phpBB/viewtopic.php?f=17&t=10. Also post your follow up discussions and comments that same forum thread.

Recently I had been working on a program to get a set of HTML files rendered in IE and then copy the contents from the IE window to a word document. I wanted to do this in VC++ since it provides very easy access to COM objects like IE, Word, etc. and I have also used it in the past to build BHOs (Browser Helper Objects) and like. VB also supports COM but usually has pretty complex procedures to do minor things. And I forgot about .NET and the wrapper libraries around COM objects which provides very easy access. If I want to do something like that I would better use C# instead. But as it goes, I started coding in VC++. The basic logic of the code is as follows:

– Ask the user the select a directory with all the HTML files that you need to put in word
– Ask the user for the word document to which the content will be put to
– Open the specified Word document and keep a handle to the application or document object
– Open an IE Window (Invisible)
– Render the HTML file in the invisible IE Window
– Select all the contents from the IE Window and Copy it to the Windows Clipboard
– and paste the clipboard contents and save the file
– Repeat the step from rendering the HTML file onwards until all the files content are in the word doc
– Save and close the word file and the application object and release all the COM instances

Sounds a bit complicated and it is since I later realized that you can use the Word Objects InsertHTMLFile() directly instead of using Windows Clipboard which is unreliable as well as open to other rogue applications which can hang this particular application. But since I want to use it for my own purposes and not productize it, I am okay with the said approach. Again, I had almost finished my whole application until I found out that information. Wish Microsoft/Bing/Google could relate such information without me explicitly asking for it.

Anyways, so after almost writing 60% of the application, I realized that my Office 2003 installation is fucked up and that the COM Wrapper classes generated in VC++ after adding an ActiveX component for Word gives a lot of compilation errors. I tried a lot of different things including using #imports of the GUID for VBE and Word with the no_implementation keyword. None worked since removal of compilation errors would turn into runtime errors when I tried to call them in the code.

Then I decided to use a C# helper program to achieve the feat. And I decided to use Anonymous Pipes to communicate between my main VC++ app and the client C# app. I didn’t want my pipes to be used by any other program as well as wanted to limit the lifetime of the handles in case any of the apps crash. Hence I used anonymous pipes instead of named pipes. And since anonymous pipe is a half-duplex/suplex pipe, I have created easy classes to both implement a Full Duplex or half-duplex anonymous pipes depending on the needs. In most cases, one would require Full Duplex pipes to ideally do a proper communication.

Download the code from http://www.naresh.se/phpBB/viewtopic.php?f=17&t=10. Also post your follow up discussions and comments that same forum thread.

GetKeyboardState() & MouseHooks – Not available in Windows Mobile

I was writing a small piece of code for Windows Mobile in C# and wanted to use GetKeyboardState() but after a lot of searching around found out that the API is not available. Also Mouse Hooks does not work in Windows Mobile. As simple as this information seems, it took me a lot of time to search and basically validate that information. Of course the various ideas and blog posts out there are pretty confusing and does not allow you to reach to a conclusion easily.

You can find the associated code in C# at http://www.naresh.se/phpBB/viewtopic.php?f=17&t=9. The code is without any cleanups now but expect a better cleaned up and documented version later on.

To give a brief:

– Extract the files in your project directory.

– In the code where you need to install and capture key events, include a private variable GlobalHooks like shown below:

private GlobalHooks globalHooks = new GlobalHooks(Process.GetCurrentProcess().MainWindowHandle);

– After initializing your other components either in the class constructor or other methods, register for the events that you would like to handle as shown below:

            globalHooks.InstallHooks();

            // Register EventHandlers
            globalHooks.KeyDown += new KeyEventHandler(globalHooks_KeyDown);
            globalHooks.KeyPress += new KeyPressEventHandler(globalHooks_KeyPress);

– Then write the associated event handler. In the following example, I have registered for KeyDown events and am suppressing the hard key LSK events.

        void globalHooks_KeyDown(object sender, KeyEventArgs e)
        {
            Debug.Write(String.Format("KeyDown: Control: {0}, Alt: {1}, Shift: {2}, KeyCode: {3}\n", e.Control, e.Alt, e.Shift, e.KeyCode));
            if (e.KeyCode == Keys.LWin || e.KeyCode == Keys.Apps)
                e.Handled = true;
        }

– No need to mention that you need to use globalHooks.RemoveHooks() once you are done with your application, else you need a reboot !

So there you go. Enjoy and give me feedback on the forum.