Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Windows-only Class WebAsyncClient #206

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Sophist-UK
Copy link
Contributor

This is an alternative way of submitting asynchronous Web calls to WenAsyncWrapper.

The WebClientAsync class truly wraps the WebClient class, providing the same methods and properties and passing them through to WebClient. It is inspired by WebAsyncWrapper and tries to make async calls as compatible as possible with WebClient.

It also provides an ExecuteAsync method that kicks off a web call (using another WebClientAsyncInstance class) and passes results or errors back to the caller using Events.

Like WebAsyncWrapper it relies on WinHttpRequest and so is Windows only (or at least until someone writes a WebHttpRequest compatible class for Mac like Tim has done with the Dictionary class). Because it returns results using Events, it can only be called from another Class module, however it is the authors belief that anyone doing Async calls is likely to be using classes anyway.

Having written and undertaken some simple tests, I am submitting this code for early review. Once I have written the real code that will use it and ironed out any bugs found, and rounded out the comments I will let you know it is ready for merging.

@timhall
Copy link
Member

timhall commented Mar 5, 2016

@Sophist-UK I like the evented approach, that'll be nice to add to VBA-Web, and the switch to Http_OnError for handling timeouts (instead of OnTime) is definitely needed. I'm not sold on proxying all the properties and methods on WebClient, that's a maintenance minefield and was the primary reason a "wrapper" was chosen for the current async functionality. The instance + Delegate approach is an interesting solution to channeling events from separate requests through the same Client, but I wonder if there is a "self-referential" approach like that used in the current wrapper that could be used to avoid adding an additional class.

I look forward to seeing this develop.

@Sophist-UK
Copy link
Contributor Author

@timhall Using a full wrapper is a trade off - ease of use for ease of maintenance. But the only maintenance is to keep the wrapper properties in line with changes to WebClient which is not too onerous IMO.

@Sophist-UK
Copy link
Contributor Author

The reason you need a Delegate is that events are only passed for the object which is referenced by the WithEvents variable, not for other instances of the same class which are held in e.g. a collection.

This is the only way that I know of to raise events from multiple instances.

@Sophist-UK
Copy link
Contributor Author

I am also pondering whether to add a request queuing mechanism to this class - to limit the number of simultaneous requests as at present there is no limit to the number that you can kick off in quick succession which could create issues either with the number of broadband router connections or Windows / Router half-open connections or trigger limits on the server (for e.g. anti-DoS).

This would work by only initiating the new request if there are <= limit number of requests already open and kicking off a new one when the previous one finishes. (Also have an ability to add Priority requests to run next by putting them at the front of the queue whilst normal requests go to the back of the queue.)

Default number of simultaneous requests would be 8 - being the limit used as standard by IE10/11 and Opera 10 - so unlikely to trigger DoS actions on a server.

@Sophist-UK
Copy link
Contributor Author

I have reloaded this branch with a modified version which includes the above enhancements plus checks for duplicate RequestRef and an Exists function.

This is an alternative way of submitting asynchronous Web calls to
WenAsyncWrapper.

The WebClientAsync class truly wraps the WebClient class, providing the
same methods and properties and passing them through to WebClient. It is
inspired by WebAsyncWrapper and tries to make async calls as compatible
as possible with WebClient.

It also provides an ExecuteAsync method that kicks off a web call (using
another WebClientAsyncInstance class) and passes results or errors back
to the caller using Events.

Like WebAsyncWrapper it relies on WinHttpRequest and so is Windows only
(or at least until someone writes a WebHttpRequest compatible class for
Mac like Tim has done with the Dictionary class). Because it returns
results using Events, it can only be called from another Class module,
however it is the authors belief that anyone doing Async calls is likely
to be using classes anyway.

Having written and undertaken some simple tests, I am submitting this
code for early review. Once I have written the real code that will use
it and ironed out any bugs found, and rounded out the comments I will
let you know it is ready for merging.
@gerald2545
Copy link

Hello Sophist,
I tried to use your classes, but without success for the moment...don't know if there is a better place to disscuss...I surely don't do the rights things....
I tried to import the cls files in the class module repository, but they appeared in the module repository. Don't think it's the right place? Then, when saving the excel file (office 2016 on windows 7, with vba-web v4.0.20), it complained about the first line "VERSION 1.0 CLASS" with a compilation error (missing end of instruction).
Any idea?
Then a question : in case I succeed to use the WebClientAsync, how can I tell my macro to wait for a batch of requests to be processed before continuing?

Hope the answers are not too trivial....
hank you for your help
Gérald

@Sophist-UK
Copy link
Contributor Author

@gerald2545 I sent you some explanation and sample code by email.

@gerald2545
Copy link

Hi,
with the help of Sophist I managed to use the async client in excel 2016.
I attached an .xlsm file example to help other people using it.
Thank you for your job and help!!!
testWS_CallAsync.zip

@Sophist-UK
Copy link
Contributor Author

My pleasure. I would like other people to enjoy the benefits of my coding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants