<body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar.g?targetBlogID\x3d6016338663470588542\x26blogName\x3dA+Guide+to+Hell\x26publishMode\x3dPUBLISH_MODE_BLOGSPOT\x26navbarType\x3dBLUE\x26layoutType\x3dCLASSIC\x26searchRoot\x3dhttps://shasini.blogspot.com/search\x26blogLocale\x3den_US\x26v\x3d2\x26homepageUrl\x3dhttp://shasini.blogspot.com/\x26vt\x3d-3621103276626359617', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>

About

"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt."

Stuffs which learnt from thread-safe communication (block current thread to wait others)

Recently I decide to rewrite my SharePoint upload tool, for improve its reliability and stabllity. One of my core idea is to use a htmlParser to analyse the HTML form out. And display all input box to users for customize the values and send to server.

After checked out a ton of c# htmlparser, I found most of them are not so intelligentized.

The one I needed is a light weight, simply use and better ability to analyse html page which has incorrect gramma.

Finally, I found the webbrowser control which integrated in vs2005 is fitting my needs.I decide to use it for my parser.

To implement a IParser interface, I must implement a Parse() method, which will return a well-formatted html document object.

Unfortunately the webbrowser control use a thread to navigate page. But my Parse() method is a single thread method, if I use webbrowser.navigate("http://sdfdf.com") directly, the Parse() method will return and I get nothing.

So, here is the problom: How to block current thread and wait for another thread finish?

My first idea is write a while(true) in main thread, and use a variable to mark whether the thread is continue or not, but it is hard to get throught because the documentComplete function will be fired by main thread -- navigate thread will send a Windows Message to main thread, then main thread invoke documentComplete function. But due to the main thread is blocked by while(true) it can't receive the message which sent by navigating thread.

So we must use some trick to make the main thread blocked and still receiving windows message.

After surfing on web, I found C# has encapluationed a WaitEventHandle (API WaitForSingleObject) and a application.DoEvent which implemented a message loop.

The waitEventHandld is the formal way to block a thread to wait the others. It use Windows Event machanism to help thread-safe communication, but it still can't receive message from queue when blocked.

Add Application.DoEvent to the while(true) scope is a feasible way. but because the main thread is waste a lot of resource for doing the loop. the cpu usage will raise up to 100%.

My mentor Jerry told me that he used to use the MsgWaitForMultipleObjects API to deal with this scenario. The MsgWaitForMultipleObjects will block if there is no message in queue and return if there is message need to be translated. A thread blocked by MsgWaitForMultipleObjects just waste a little bit system resource. It only let go my PeekMessage loop when a message comes. It is the best way to deal with this scenario. After I add a simply loop to receive message my parser works:)


WindowsEvent.MSG msg = new WindowsEvent.MSG();
mySafeWaitHandle = myEventWaitHandle.SafeWaitHandle;
while (WindowsEvent.MsgWaitForMultipleObjects(1, ref mySafeWaitHandle, false, 3000, WindowsEvent.QS_ALLEVENTS) != 0)
{
while (WindowsEvent.PeekMessage(ref msg, 0, 0, 0, WindowsEvent.PeekMessageOption.PM_REMOVE))
{

WindowsEvent.TranslateMessage(ref msg);
WindowsEvent.DispatchMessage(ref msg);
}
//you can use Application.DoEvents(); to instead of peekmessage... but I want to do it myself for learning C# P/invoke.
}




How to do a API invoke in c# (p/invoke)
http://msdn.microsoft.com/msdnmag/issues/03/07/NET/
A thread related to message loop help you understand it:
http://www.gamedev.net/community/forums/topic.asp?topic_id=207360
Understand the message loop:
http://www.winprog.org/tutorial/message_loop.html
Definition of MSG(struct of message):
http://msdn2.microsoft.com/en-us/library/aa929818.aspx
PeekMessage on MSDN:
http://msdn2.microsoft.com/en-us/library/aa924590.aspx
MsgWaitForMultipleObjectEx:
http://msdn2.microsoft.com/en-us/library/aa931971.aspx

Sample:
http://www.codeguru.com/forum/showthread.php?t=363382

Labels: ,

You can leave your response or bookmark this post to del.icio.us by using the links below.
Comment | Bookmark | Go to end