Jump to content

Blocking behavior with WinHttpRequest object (ActiveX/Automation)


Recommended Posts

I encountered this bizarre and performance-destroying behavior yesterday so I thought I should write up some notes on it.

In our application we call various Microsoft components (Active Data Objects, WinHTTP, MSXML) to do tasks that aren't build-in to LabView (database connectivity, http and xpath queries, respectively.) We use the Automation (ActiveX) functions for this. When we expect to call these routines in parallel, their wrappers are set for re-entrant execution.

I was running a process that does a lot of downloading via WinHTTP in one thread while doing a lot of opening and closing of databases in another. I was getting extremely poor performance. A little debugging isolated the problem to a block on the Automation Open function (on an ADO object!) while WinHTTP was doing a synchronous download. Adding more parallel downloads makes the problem worse; I have no trouble firing off 5 WinHTTP downloads in parallel, but doing so almost completely lobotomizes LabView. Click the run button with five WinHTTP clones chomping away at big files and even the simplest routines (see two-plus-two.png) get completely stuck.

The solution is simple: enable asynchronous downloads. From the WinHttpRequest documentation.

"The main advantage to using WinHTTP asynchronously in script is that the Send method returns immediately. The request is prepared and sent by a worker thread. This enables your application to do other things while it is waiting for the response. "

We had set it to synchronous because a) it was the default and b) we were running it in a clone anyway and didn't really want the clone to do anything other than wait for the download to complete. What I did not realize is that when Microsoft says "[t]his enables your application to do other things while it is waiting for the response", they are not kidding! The WinHttpRequest.Send method apparently has deep ties into the depths of the Windows execution system and you REALLY cannot do other things while it is running.

The strangest part of the whole business is that while you can set up an ActiveX event to catch the completion notice, if you don't mind you VI (as opposed to your entire application) to get blocked, the easy way to do a download is to fire off the request with WinHttpRequest.Send (async) and then wait (synchronously) for it to complete or timeout using WinHttpRequest.WaitForResponse. WinHttpRequest.WaitForResponse blocks your VI but it doesn't destroy your world.

So in the end this had an easy solution. (And I was really sweating this last night!) This kind of issue, however, is why Jim and I would like to see a nice SSL-capable http client built in to LabView. (see Setting up SSL Web Services).

Here is the synchronous (blocking) code. DON'T DO THIS!

Here is the non-blocking) code. You can use an ActiveX event if you want to show a progress bar or something, but this will get the job done.

-Rob Calhoun

blocked!

post-15310-124966470219_thumb.png

blocking:

post-15310-12496647159_thumb.png

non-blocking:

post-15310-124966472783_thumb.png

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.