WebClient.DownloadFileAsync

WebClient.DownloadFileAsync

am 02.03.2006 22:58:30 von 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?
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

Re: WebClient.DownloadFileAsync

am 02.03.2006 23:10:41 von 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,
--
Joerg Jooss
news-reply@joergjooss.de

Re: WebClient.DownloadFileAsync

am 03.03.2006 18:22:26 von 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.


Giovanni

"Joerg Jooss" wrote:

> 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,
> --
> Joerg Jooss
> news-reply@joergjooss.de
>
>
>

Re: WebClient.DownloadFileAsync

am 03.03.2006 20:50:55 von 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,
--
Joerg Jooss
news-reply@joergjooss.de

Re: WebClient.DownloadFileAsync

am 03.03.2006 23:13:29 von 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?

Thank you for your input.

Regards,

Giovanni

"Joerg Jooss" wrote:

> 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,
> --
> Joerg Jooss
> news-reply@joergjooss.de
>
>
>

Re: WebClient.DownloadFileAsync

am 04.03.2006 10:39:07 von 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,
--
Joerg Jooss
news-reply@joergjooss.de

Re: WebClient.DownloadFileAsync

am 05.03.2006 04:16:27 von Giovanni

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