WebClient.DownloadFileAsync

G

Guest

Hi Guys,

Really strange problem I am experiencing... I have setup a virtual
directory with Read Only permissions on an ISA/IIS server (SBS 2003). In
that virt. dir., I placed 1 file (setup.exe). I then use
WebClient.DownloadFileAsync (.NET 2.0 Pro.) and all downloads well including
progress bar indicator, bytes received, etc... Here is the problem:

When I replace the file (setup.exe), with a different, larger file, it
still downloads the old/original one. I guess ISA/IIS server must keep a
cache of it somewhere. I've searched the entire hard drive, but cannot find
it. Is there any way to circumvent this caching which is causing my problem?
I don't think it has anything to do with my code as I receive the file
properly. The only issue is that if I were to replace the same file, with a
newer version, it still downloads the old one...

Regards,

Giovanni
 
J

Joerg Jooss

Thus wrote Giovanni,
Hi Guys,

Really strange problem I am experiencing... I have setup a
virtual directory with Read Only permissions on an ISA/IIS server (SBS
2003). In that virt. dir., I placed 1 file (setup.exe). I then use
WebClient.DownloadFileAsync (.NET 2.0 Pro.) and all downloads well
including progress bar indicator, bytes received, etc... Here is the
problem:

When I replace the file (setup.exe), with a different, larger
file, it
still downloads the old/original one. I guess ISA/IIS server must
keep a
cache of it somewhere. I've searched the entire hard drive, but
cannot find
it. Is there any way to circumvent this caching which is causing my
problem?

You can control caching from the client side using WebClient.CachePolicy
property.

RequestCachePolicy policy = new RequestCachePolicy(RequestCacheLevel.Reload);
WebClient client = new WebClient();
client.CachePolicy = policy;

Cheers,
 
G

Guest

Hi Joerg,

Thank you for your answer. It worked as soon as I implemented your
solution. I do have one other small issue now. I need to download more than
one file at once; maybe 2-3. I have the DownloadFileAsync working properly
(it seems to), but when I try to start call the DownloadFileAsync method
again specifying another source and destination, it gives me the following
error:

WebClient does not support concurrent I/O operations.

System.NotSupportedException was caught
Message="WebClient does not support concurrent I/O operations."
Source="System"
StackTrace:
at System.Net.WebClient.ClearWebClientState()
at System.Net.WebClient.DownloadFileAsync(Uri address, String
fileName, Object userToken)
at System.Net.WebClient.DownloadFileAsync(Uri address, String fileName)
at WindowsApplication1.Form1.btnDownload_Click(Object sender,
EventArgs e) in C:\Documents and Settings\test\My Documents\Visual Studio
2005\Projects\WindowsApplication1\WindowsApplication1\Form1.vb:line 43


Any ideas why? Thanks for all your help on this. I really appreciate it.


Giovanni
 
J

Joerg Jooss

Thus wrote Giovanni,
Hi Joerg,

Thank you for your answer. It worked as soon as I implemented
your solution. I do have one other small issue now. I need to
download more than one file at once; maybe 2-3. I have the
DownloadFileAsync working properly (it seems to), but when I try to
start call the DownloadFileAsync method again specifying another
source and destination, it gives me the following error:

WebClient does not support concurrent I/O operations.

System.NotSupportedException was caught
Message="WebClient does not support concurrent I/O operations."
Source="System"
StackTrace:
at System.Net.WebClient.ClearWebClientState()
at System.Net.WebClient.DownloadFileAsync(Uri address, String
fileName, Object userToken)
at System.Net.WebClient.DownloadFileAsync(Uri address, String
fileName)
at WindowsApplication1.Form1.btnDownload_Click(Object sender,
EventArgs e) in C:\Documents and Settings\test\My Documents\Visual
Studio
2005\Projects\WindowsApplication1\WindowsApplication1\Form1.vb:line 43

Any ideas why? Thanks for all your help on this. I really appreciate
it.

I don't think you can use a single WebClient instance to execute several
HTTP requests at the same time. Try to create a WebClient instance per request,
that should work just fine.

Cheers,
 
G

Guest

Hi Joerg,

Thank you once again for your help. I've declared a second object and
also initiated the download at the same time as the first. All worked well.
What I'd like to do is now make this approcah more generalized, i.e., build a
class, add a file to download and begin the download progress asynchronously,
while updating a (new) progress bar for each file being downloaded. The
class part is what fumbles me a little. Any ideas on whether I should use
threads or does the DownloadFileAsync method automatically use a thread from
the existing thread pool provided. Should I provide callbacks
(IAsyncResult), or just raise events from my class for the
DownloadFileComplete or DownloadProgressChange events. Do Delegates fit into
this picture?

Thank you for your input.

Regards,

Giovanni
 
J

Joerg Jooss

Thus wrote Giovanni,
Hi Joerg,

Thank you once again for your help. I've declared a second
object and also initiated the download at the same time as the first.
All worked well. What I'd like to do is now make this approcah more
generalized, i.e., build a class, add a file to download and begin the
download progress asynchronously, while updating a (new) progress bar
for each file being downloaded. The class part is what fumbles me a
little. Any ideas on whether I should use threads or does the
DownloadFileAsync method automatically use a thread from the existing
thread pool provided. Should I provide callbacks (IAsyncResult), or
just raise events from my class for the DownloadFileComplete or
DownloadProgressChange events. Do Delegates fit into this picture?

DownloadFileAsync will execute the callback on a threadpool thread.

The question is what kind of programming model you want to offer to your
component's users (i.e. developers). The best approach is certainly to offer
events. Since the actual number of event sources varies in your case (it's
bound to the number of active WebClients), you'll need some way of mapping
the underyling WebClient event to your own event. From a programming perspective,
it's probably easier for you if you just add a delegate to your own Download()
method, and call the delegate for each progress bar step.

Cheers,
 
G

Guest

Hi Joerg,

The class I'd like to build would be instanced several times in a
WinForms application. I'd specify a separate progressbar for every new
instance of the class and begin the download. I am having a problem
conceptualizing the way my class is to be built and the way each individual
instance is to communicate with a specific progress bar and raise the events.
It's blurry. I have searched the internet for examples of the WebClient
class being used in a custom built class that downloads multiple files but
nothing so far. Would you know of any (VB.NET prefferably)? This is what I
have so far. Is my class on the right track? Just want to know if they way
I am raising events to a WindowsForms client from a .dll is the correct way
and the way I cancel the operation is also OK. Thanks again for your help.


'Declared in another .VB file.

Public Delegate Sub DownloadCompleteHandler(ByVal sender As Object, _
ByVal e As DownloadDataCompletedEventArgs)

Public Delegate Sub DownloadProgressChangeHandler(ByVal sender As Object,_
ByVal e As DownloadProgressChangedEventArgs)


Public Class AutoUpdate
Private _WebClient As WebClient
Private _DownloadURL As String

Public Event CompleteCallback As DownloadCompleteHandler
Public Event ProgressCallback As DownloadProgressChangeHandler

Public Sub New()
'Base constructor.
End Sub

Public Sub New(ByVal downloadURL As String, ByVal destination As
String)
_WebClient = New WebClient
AddHandler _WebClient.DownloadFileCompleted, _
AddressOf DownloadCompleteHandler

AddHandler _WebClient.DownloadProgressChanged, _
AddressOf DownloadProgressChangedHandler

_WebClient.DownloadFileAsync(New Uri(downloadURL), destination)
End Sub

Public Property DownloadURL() As String
Get
Return Me._DownloadURL
End Get
Set(ByVal value As String)
Me._DownloadURL = value
End Set
End Property

Public Sub DownloadCompleteHandler(ByVal sender As Object, _
ByVal e As ComponentModel.AsyncCompletedEventArgs)

RaiseEvent CompleteCallback(sender, e)

End Sub

Public Sub DownloadProgressChangedHandler(ByVal sender As Object, _
ByVal e As Net.DownloadProgressChangedEventArgs)

RaiseEvent ProgressCallback(sender, e)
End Sub

Public Sub Cancel()
_WebClient.CancelAsync()
End Sub
End Class
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top