Discussion:
Asynch wininet - Threaded or not?
(too old to reply)
Fred
2006-02-01 14:51:49 UTC
Permalink
Hi,

If I use asynch Wininet is there any purpose in hiving of the Wininet calls
into separate threads and the extra complication which ensues? As from what
I can see the system starts a separate thread implicitly for the asynch
calls anyway.
The reason I ask is I imagine the thread switching might ensure that the UI
remains responsive - plus there may be other issues you can enlighten me
with.

My application is "real-time" and will be applied to a Pocket PC/Smartphone
as well as WinXP so I need the quickest/most efficient functionality
possible.

Also the UI response must be as fast as possible.

The application basically "GET"s a website for info then issues occasional -
through crucial "POST"s prompted by the user via the UI.

Both the GETS and POSTS must be carried out as close to real-time as
possible.

TIA
Paul Baker
2006-02-01 16:58:29 UTC
Permalink
My preference is to use WinInet synchronously in a multi-threaded
environment.

Paul
Post by Fred
Hi,
If I use asynch Wininet is there any purpose in hiving of the Wininet calls
into separate threads and the extra complication which ensues? As from what
I can see the system starts a separate thread implicitly for the asynch
calls anyway.
The reason I ask is I imagine the thread switching might ensure that the UI
remains responsive - plus there may be other issues you can enlighten me
with.
My application is "real-time" and will be applied to a Pocket
PC/Smartphone
as well as WinXP so I need the quickest/most efficient functionality
possible.
Also the UI response must be as fast as possible.
The application basically "GET"s a website for info then issues occasional -
through crucial "POST"s prompted by the user via the UI.
Both the GETS and POSTS must be carried out as close to real-time as
possible.
TIA
Fred
2006-02-02 01:31:15 UTC
Permalink
Post by Paul Baker
My preference is to use WinInet synchronously in a multi-threaded
environment.
Hi,

Is it just a preference or have you experienced better performance?

See also my post about hanging threads. They cannot easily be handled in a
synchronous environment (AFAIK ).
As INTERNET_OPTION_CONNECT_TIMEOUT doesn't work.
Paul Baker
2006-02-02 14:03:22 UTC
Permalink
Fred,

As far as I know, INTERNET_OPTION_CONNECT_TIMEOUT does work. Rather than
base the entire design of your software on the premise that it does not, I
would go into more detail about that here and someone should be able to help
you. You might also closely review the documentation regarding the use of
this constant.

It does not affect performance. It's simply easier to use WinInet
synchronously rather than asynchronously. And creating a thread is almost
trivial.

To terminate a synchronous operation, all you need to do is close the handle
on which it acts or one if its parents.

Paul
Post by Fred
Post by Paul Baker
My preference is to use WinInet synchronously in a multi-threaded
environment.
Hi,
Is it just a preference or have you experienced better performance?
See also my post about hanging threads. They cannot easily be handled in a
synchronous environment (AFAIK ).
As INTERNET_OPTION_CONNECT_TIMEOUT doesn't work.
Fred
2006-02-02 19:24:56 UTC
Permalink
Post by Paul Baker
Fred,
As far as I know, INTERNET_OPTION_CONNECT_TIMEOUT does work.
Nope, it doesn't - in synchronous mode anyway.
Post by Paul Baker
Hello
Based on Stephen's post I went and took a look at some old bug reports and
found he is correct. They never fixed INTERNET_OPTION_CONNECT_TIMEOUT as
the timeout is imposed by winsock layer.
They do appear to have fixed the
INTERNET_OPTION_RECEIVE_TIMEOUT
INTERNET_OPTION_SEND_TIMEOUT
for HTTP only.
Rather than
base the entire design of your software on the premise that it does not, I
would go into more detail about that here and someone should be able to help
you. You might also closely review the documentation regarding the use of
this constant.
It does not affect performance. It's simply easier to use WinInet
synchronously rather than asynchronously. And creating a thread is almost
trivial.
To terminate a synchronous operation, all you need to do is close the handle
on which it acts or one if its parents.
I think I'll write both :-)

Of course then we have thread pooling etc unless I create a thred for each
request and the application will need to run on a smartphone/pocket PC too.
Fred
2006-02-02 19:38:48 UTC
Permalink
Post by Paul Baker
Fred,
As far as I know, INTERNET_OPTION_CONNECT_TIMEOUT does work. Rather than
base the entire design of your software on the premise that it does not, I
would go into more detail about that here and someone should be able to help
you. You might also closely review the documentation regarding the use of
this constant.
It does not affect performance. It's simply easier to use WinInet
synchronously rather than asynchronously. And creating a thread is almost
trivial.
To terminate a synchronous operation, all you need to do is close the handle
on which it acts or one if its parents.
Could you be explicit with a code snippet as I remain confused given the MS
support docs

http://support.microsoft.com/kb/176420/EN-US/
http://support.microsoft.com/kb/224318/EN-US/

Say I have several threads carrying out their own requests. One of them is
taking too long.
and I wish to terminate that request yet leave the others untouched.

How do i do it?

Thanks
Paul Baker
2006-02-02 20:13:48 UTC
Permalink
Just close the handle to the request you wish to cancel with
InternetCloseHandle.

Paul
Post by Fred
Post by Paul Baker
Fred,
As far as I know, INTERNET_OPTION_CONNECT_TIMEOUT does work. Rather than
base the entire design of your software on the premise that it does not, I
would go into more detail about that here and someone should be able to
help
Post by Paul Baker
you. You might also closely review the documentation regarding the use of
this constant.
It does not affect performance. It's simply easier to use WinInet
synchronously rather than asynchronously. And creating a thread is almost
trivial.
To terminate a synchronous operation, all you need to do is close the
handle
Post by Paul Baker
on which it acts or one if its parents.
Could you be explicit with a code snippet as I remain confused given the MS
support docs
http://support.microsoft.com/kb/176420/EN-US/
http://support.microsoft.com/kb/224318/EN-US/
Say I have several threads carrying out their own requests. One of them is
taking too long.
and I wish to terminate that request yet leave the others untouched.
How do i do it?
Thanks
Scherbina Vladimir
2006-02-02 20:24:13 UTC
Permalink
Associate handle of thread with a list of HINTERNET handles that are using
in thread. When you see that thread is working "too long", call
InternetCloseHandle on those HINTERNET handles. This is the simplest
solution.
--
Vladimir
Post by Fred
Post by Paul Baker
Fred,
As far as I know, INTERNET_OPTION_CONNECT_TIMEOUT does work. Rather than
base the entire design of your software on the premise that it does not, I
would go into more detail about that here and someone should be able to
help
Post by Paul Baker
you. You might also closely review the documentation regarding the use of
this constant.
It does not affect performance. It's simply easier to use WinInet
synchronously rather than asynchronously. And creating a thread is almost
trivial.
To terminate a synchronous operation, all you need to do is close the
handle
Post by Paul Baker
on which it acts or one if its parents.
Could you be explicit with a code snippet as I remain confused given the MS
support docs
http://support.microsoft.com/kb/176420/EN-US/
http://support.microsoft.com/kb/224318/EN-US/
Say I have several threads carrying out their own requests. One of them is
taking too long.
and I wish to terminate that request yet leave the others untouched.
How do i do it?
Thanks
Fred
2006-02-03 12:05:21 UTC
Permalink
Post by Scherbina Vladimir
Associate handle of thread with a list of HINTERNET handles that are using
in thread. When you see that thread is working "too long", call
InternetCloseHandle on those HINTERNET handles. This is the simplest
solution.
Hi,

The demo http://support.microsoft.com/kb/224318/EN-US/

uses the handle for InternetOpen () to close the thread if the thread is
hanging. So if I have multiple connections (threads) from the one
InternetOpen () (which is the recommended technique) then any wininet
activity must surely be terminated on *all* these threads - which is not
what I want.

Now documentation states:

"The application can make any number of calls to InternetOpen, though a
single call is normally sufficient. "

So to stop one hanging thread then I would have to have a separate
InternetOpen for each thread and then a separate Internetconnect() too -
what is the overhead for this? Surely it is more than marginal - and don't
forget I will be porting to SmartPhone which has nowhere near the horsepower
of a PC.

These above concerns are the issues which prompted my initial post.

So, how do you handle hanging/blocking threads? Terminating them all when
only one is blocking, say on an InternetReadFile() cannot be the ideal
solution.

Further can you actual terminate on any blocking wininet function, say if
InternetReadFile() is blocking or does it only work for Internetconnect?

Thanks
Scherbina Vladimir
2006-02-03 12:59:31 UTC
Permalink
Hello, Fred.
Post by Fred
The demo http://support.microsoft.com/kb/224318/EN-US/
uses the handle for InternetOpen () to close the thread if the thread is
hanging. So if I have multiple connections (threads) from the one
InternetOpen () (which is the recommended technique) then any wininet
activity must surely be terminated on *all* these threads - which is not
what I want.
"The application can make any number of calls to InternetOpen, though a
single call is normally sufficient. "
So to stop one hanging thread then I would have to have a separate
InternetOpen for each thread and then a separate Internetconnect() too -
what is the overhead for this? Surely it is more than marginal - and don't
forget I will be porting to SmartPhone which has nowhere near the horsepower
of a PC.
These above concerns are the issues which prompted my initial post.
So, how do you handle hanging/blocking threads? Terminating them all when
only one is blocking, say on an InternetReadFile() cannot be the ideal
solution.
Further can you actual terminate on any blocking wininet function, say if
InternetReadFile() is blocking or does it only work for Internetconnect?
Thanks
There is no need to make an InternetOpen in all threads - this is a really
overhead. You may call InternetOpen once and use returned handle in all
threads.

Each thread (or thread from the pool) makes InternetConnect using handle
returned by InternetOpen. Most likely your thread would not be blocked by
call of InternetConnect, it might hung when you will make call to
HttpOpenRequest / HttpSendRequst, so to cancel blocking of thread you should
close handle of request(or whatever) it made. Microsofts examples closes
handle returned by InternetOpen, but you may cancel execution closing handle
returned by HttpOpenRequest or simular function.

So, once more:

1. Locate where your thread may hung (InternetReadFile, HttpSendRequest,
etc)
2. Associate HINTERNET handles open by thread with thread's handle.
3. Mark position *what* wininet function is executed in each thread.
4. When thread is hung, read the position - you know what function is
executed, and the handle it uses, simply close it.

--
Vladimir
Fred
2006-02-03 18:36:17 UTC
Permalink
Post by Scherbina Vladimir
Hello, Fred.
Each thread (or thread from the pool) makes InternetConnect using handle
returned by InternetOpen. Most likely your thread would not be blocked by
call of InternetConnect, it might hung when you will make call to
HttpOpenRequest / HttpSendRequst, so to cancel blocking of thread you should
close handle of request(or whatever) it made. Microsofts examples closes
handle returned by InternetOpen, but you may cancel execution closing handle
returned by HttpOpenRequest or simular function.
1. Locate where your thread may hung (InternetReadFile, HttpSendRequest,
etc)
2. Associate HINTERNET handles open by thread with thread's handle.
3. Mark position *what* wininet function is executed in each thread.
4. When thread is hung, read the position - you know what function is
executed, and the handle it uses, simply close it.
OK,

I'll try it.

Cheers

Scherbina Vladimir
2006-02-01 21:27:06 UTC
Permalink
Hello, Fred.
Post by Fred
Hi,
If I use asynch Wininet is there any purpose in hiving of the Wininet calls
into separate threads and the extra complication which ensues? As from what
I can see the system starts a separate thread implicitly for the asynch
calls anyway.
The reason I ask is I imagine the thread switching might ensure that the UI
remains responsive - plus there may be other issues you can enlighten me
with.
My application is "real-time" and will be applied to a Pocket
PC/Smartphone
as well as WinXP so I need the quickest/most efficient functionality
possible.
Also the UI response must be as fast as possible.
The application basically "GET"s a website for info then issues occasional -
through crucial "POST"s prompted by the user via the UI.
Both the GETS and POSTS must be carried out as close to real-time as
possible.
TIA
Even if you use wininet synchronously system might create additional threads
and you cannot control this behavour. So putting async. calls into separate
thread is useless.

You may achieve the fastest result by creating the "worker" thread that
waits on some object (for instance, event) and when GUI thread is going to
make a GET or POST it sets the event and allows worker thread to accomplish
the actual work using syncronous wininet calls.
--
Vladimir
Fred
2006-02-02 00:58:04 UTC
Permalink
Post by Scherbina Vladimir
Hello, Fred.
Even if you use wininet synchronously system might create additional threads
and you cannot control this behavour. So putting async. calls into separate
thread is useless.
You may achieve the fastest result by creating the "worker" thread that
waits on some object (for instance, event) and when GUI thread is going to
make a GET or POST it sets the event and allows worker thread to accomplish
the actual work using syncronous wininet calls.
--
Vladimir
Hi,

I have built a related application which uses synchronous Wininet. However I
have never worked out how to terminate a single thread if it hangs. The MS
workarounds to the wininet bug seem to terminate all active Wininet calls.
Scherbina Vladimir
2006-02-02 05:33:50 UTC
Permalink
Post by Fred
Hi,
I have built a related application which uses synchronous Wininet. However I
have never worked out how to terminate a single thread if it hangs. The MS
workarounds to the wininet bug seem to terminate all active Wininet calls.
Documentation states that if you have a thread that is reading or writing
something to/from stream using HINTERNET handle you can close that handle on
another thread using InternetCloseHandle. So if you have you "worker"
sending POST or GET via HttpSendRequest closing HINTERNET handle that is
used in HttpSendRequest will cancel sending request.
--
Vladimir
Fred
2006-02-02 11:31:46 UTC
Permalink
Post by Scherbina Vladimir
Post by Fred
Hi,
I have built a related application which uses synchronous Wininet.
However
Post by Scherbina Vladimir
Post by Fred
I
have never worked out how to terminate a single thread if it hangs. The MS
workarounds to the wininet bug seem to terminate all active Wininet calls.
Documentation states that if you have a thread that is reading or writing
something to/from stream using HINTERNET handle you can close that handle on
another thread using InternetCloseHandle. So if you have you "worker"
sending POST or GET via HttpSendRequest closing HINTERNET handle that is
used in HttpSendRequest will cancel sending request.
I have read that the cancelling thread MS fix,
http://support.microsoft.com/kb/224318/EN-US/ will cancell all threads
currently accessing the Internet - although I can't find the original
reference which details this.

I have also come across this assertion:

"The async mode is most suited to applications which must be single threaded
and stay responsive to the end user and in extreme performance and memory
sensitive situations"

Although that was in a very old book :)
Paul Baker
2006-02-02 14:26:34 UTC
Permalink
Fred,

Let's discuss what your old book says:

"The async mode is most suited to applications which must be single threaded
and stay responsive to the end user and in extreme performance and memory
sensitive situations"

This is technically true, but don't be misled by it!

If an application must be single threaded, then synchronous mode by
definition will prevent it from returning to the message loop until it is
done. However, there is no such application in practice. Who's stopping you
from using multiple threads? Nobody! Only your own lack of knowledge about
multithreaded programming, perhaps.

The rest of it is presumably talking about the expense of creating a thread.
It takes a little time and it allocates some memory (the largest part of
which is the stack). However, these are not really relevant issues for most
applications. You're not going to be downloading thousands of web pages at
once are you? If you are, then you should not be using WinInet. You should
be using WinHTTP.

Paul
Post by Fred
Post by Scherbina Vladimir
Post by Fred
Hi,
I have built a related application which uses synchronous Wininet.
However
Post by Scherbina Vladimir
Post by Fred
I
have never worked out how to terminate a single thread if it hangs. The
MS
Post by Scherbina Vladimir
Post by Fred
workarounds to the wininet bug seem to terminate all active Wininet
calls.
Post by Scherbina Vladimir
Documentation states that if you have a thread that is reading or writing
something to/from stream using HINTERNET handle you can close that handle
on
Post by Scherbina Vladimir
another thread using InternetCloseHandle. So if you have you "worker"
sending POST or GET via HttpSendRequest closing HINTERNET handle that is
used in HttpSendRequest will cancel sending request.
I have read that the cancelling thread MS fix,
http://support.microsoft.com/kb/224318/EN-US/ will cancell all threads
currently accessing the Internet - although I can't find the original
reference which details this.
"The async mode is most suited to applications which must be single threaded
and stay responsive to the end user and in extreme performance and memory
sensitive situations"
Although that was in a very old book :)
Fred
2006-02-02 19:40:44 UTC
Permalink
Post by Fred
Fred,
"The async mode is most suited to applications which must be single threaded
and stay responsive to the end user and in extreme performance and memory
sensitive situations"
This is technically true, but don't be misled by it!
If an application must be single threaded, then synchronous mode by
definition will prevent it from returning to the message loop until it is
done. However, there is no such application in practice. Who's stopping you
from using multiple threads? Nobody! Only your own lack of knowledge about
multithreaded programming, perhaps.
Yes as far as synchronous/asynchronous Wininet and multithreading is
concerned.
I have written a pretty complicated prog with a thread pool and synchronous
Wininet and it works - but I'm still not happy about cancelling threads when
we have a timed-out block.
Post by Fred
The rest of it is presumably talking about the expense of creating a thread.
It takes a little time and it allocates some memory (the largest part of
which is the stack). However, these are not really relevant issues for most
applications. You're not going to be downloading thousands of web pages at
once are you?
What is the extra complexity involved in writing asynch wininet?

MS's asyncdemo doesn't look too bad

http://msdn.microsoft.com/library/en-us/wininet/wininet/calling_wininet_functions_asynchronously.asp
Fred
2006-02-02 19:48:24 UTC
Permalink
Post by Paul Baker
Post by Fred
Fred,
"The async mode is most suited to applications which must be single
threaded
Post by Fred
and stay responsive to the end user and in extreme performance and memory
sensitive situations"
This is technically true, but don't be misled by it!
If an application must be single threaded, then synchronous mode by
definition will prevent it from returning to the message loop until it is
done. However, there is no such application in practice. Who's stopping
you
Post by Fred
from using multiple threads? Nobody! Only your own lack of knowledge about
multithreaded programming, perhaps.
Yes as far as synchronous/asynchronous Wininet and multithreading is
concerned.
I have written a pretty complicated prog with a thread pool and synchronous
Wininet and it works - but I'm still not happy about cancelling threads when
we have a timed-out block.
Post by Fred
The rest of it is presumably talking about the expense of creating a
thread.
Post by Fred
It takes a little time and it allocates some memory (the largest part of
which is the stack). However, these are not really relevant issues for
most
Post by Fred
applications. You're not going to be downloading thousands of web pages at
once are you?
What is the extra complexity involved in writing asynch wininet?
MS's asyncdemo doesn't look too bad
http://msdn.microsoft.com/library/en-us/wininet/wininet/calling_wininet_functions_asynchronously.asp
Incidentally it also uses threads!!!!!!
Paul Baker
2006-02-02 20:13:01 UTC
Permalink
Yes, their use of threads is a little odd IMO.

Asynchronous operation is indeed not that bad, but I never understood the
point of it. Maybe it's just a matter of preference.

Paul
Post by Fred
Post by Paul Baker
Post by Fred
Fred,
"The async mode is most suited to applications which must be single
threaded
Post by Fred
and stay responsive to the end user and in extreme performance and
memory
Post by Paul Baker
Post by Fred
sensitive situations"
This is technically true, but don't be misled by it!
If an application must be single threaded, then synchronous mode by
definition will prevent it from returning to the message loop until it
is
Post by Paul Baker
Post by Fred
done. However, there is no such application in practice. Who's stopping
you
Post by Fred
from using multiple threads? Nobody! Only your own lack of knowledge
about
Post by Paul Baker
Post by Fred
multithreaded programming, perhaps.
Yes as far as synchronous/asynchronous Wininet and multithreading is
concerned.
I have written a pretty complicated prog with a thread pool and
synchronous
Post by Paul Baker
Wininet and it works - but I'm still not happy about cancelling threads
when
Post by Paul Baker
we have a timed-out block.
Post by Fred
The rest of it is presumably talking about the expense of creating a
thread.
Post by Fred
It takes a little time and it allocates some memory (the largest part of
which is the stack). However, these are not really relevant issues for
most
Post by Fred
applications. You're not going to be downloading thousands of web pages
at
Post by Paul Baker
Post by Fred
once are you?
What is the extra complexity involved in writing asynch wininet?
MS's asyncdemo doesn't look too bad
http://msdn.microsoft.com/library/en-us/wininet/wininet/calling_wininet_functions_asynchronously.asp
Incidentally it also uses threads!!!!!!
Paul Baker
2006-02-02 14:06:57 UTC
Permalink
Never mind, you are referring to this, I think:

BUG: InternetSetOption Does Not Set Timeout Values
http://support.microsoft.com/kb/176420/EN-US/

Isn't the default timeout acceptable? This has never been an issue for me.

Paul
Post by Paul Baker
Fred,
As far as I know, INTERNET_OPTION_CONNECT_TIMEOUT does work. Rather than
base the entire design of your software on the premise that it does not, I
would go into more detail about that here and someone should be able to
help you. You might also closely review the documentation regarding the
use of this constant.
It does not affect performance. It's simply easier to use WinInet
synchronously rather than asynchronously. And creating a thread is almost
trivial.
To terminate a synchronous operation, all you need to do is close the
handle on which it acts or one if its parents.
Paul
Post by Fred
Post by Paul Baker
My preference is to use WinInet synchronously in a multi-threaded
environment.
Hi,
Is it just a preference or have you experienced better performance?
See also my post about hanging threads. They cannot easily be handled in
a
synchronous environment (AFAIK ).
As INTERNET_OPTION_CONNECT_TIMEOUT doesn't work.
Fred
2006-02-02 19:45:04 UTC
Permalink
Post by Paul Baker
BUG: InternetSetOption Does Not Set Timeout Values
http://support.microsoft.com/kb/176420/EN-US/
Isn't the default timeout acceptable? This has never been an issue for me.
Paul
Hi Paul.

(I've just made another couple of posts discussing it before this one of
yours came through.)


Nope its not. Mine is a "real-time" application" If the thread hangs more
than a second or two waiting for a response it's useless.

Also does the default timeout work OK? I've had problems with threads
hanging indefinitely.
Paul Baker
2006-02-02 20:14:53 UTC
Permalink
I don't really know much about timeout behaviour.

I have seen a DNS timeout within a few seconds (but more than two).

I haven't seen an HTTP timeout. Are the web servers you're connecting to
really unreliable or something?

Paul
Post by Fred
Post by Paul Baker
BUG: InternetSetOption Does Not Set Timeout Values
http://support.microsoft.com/kb/176420/EN-US/
Isn't the default timeout acceptable? This has never been an issue for me.
Paul
Hi Paul.
(I've just made another couple of posts discussing it before this one of
yours came through.)
Nope its not. Mine is a "real-time" application" If the thread hangs more
than a second or two waiting for a response it's useless.
Also does the default timeout work OK? I've had problems with threads
hanging indefinitely.
Scherbina Vladimir
2006-02-02 20:27:00 UTC
Permalink
You should always be ready and handle unreliable connections in your code.
As for HTTP, server usually responses and break connection - to handle next
one.
--
Vladimir
Post by Paul Baker
I don't really know much about timeout behaviour.
I have seen a DNS timeout within a few seconds (but more than two).
I haven't seen an HTTP timeout. Are the web servers you're connecting to
really unreliable or something?
Paul
Post by Fred
Post by Paul Baker
BUG: InternetSetOption Does Not Set Timeout Values
http://support.microsoft.com/kb/176420/EN-US/
Isn't the default timeout acceptable? This has never been an issue for me.
Paul
Hi Paul.
(I've just made another couple of posts discussing it before this one of
yours came through.)
Nope its not. Mine is a "real-time" application" If the thread hangs more
than a second or two waiting for a response it's useless.
Also does the default timeout work OK? I've had problems with threads
hanging indefinitely.
Fred
2006-02-03 12:13:16 UTC
Permalink
Post by Paul Baker
I don't really know much about timeout behaviour.
I have seen a DNS timeout within a few seconds (but more than two).
I haven't seen an HTTP timeout. Are the web servers you're connecting to
really unreliable or something?
It's not that they are particularly unreliable - I need "real time"
response. The real issue is not around connecting (I suppose) but around
reading the servers response.


If the data is not downloaded "immediately" then it is out of date and so
useless.

On my other app using synch wininet and threads the threads seem to hang -
never timeout - if the site is slow to respond for that request - of course
there could be other issues causing this as its really hard to pin down.
Loading...