winforms icon indicating copy to clipboard operation
winforms copied to clipboard

Add Async versions of DownloadFile

Open paul1956 opened this issue 1 year ago • 3 comments

Background and motivation

In order to update Microsoft.VisualBasic.Devices.Network to use HttpClient a set of DownloadFileAsyc needed to be create but they are now Friend Shared. It would be useful if the Async versions were available to developers, and they are already written and tested.

API Proposal

It is possible to match all the current Microsoft.VisualBasic.Devices.Network.DownloadFile API but the set below is also reasonable. It is also possible to have many few using optional parameters. Some below are currently commented out as unnecessary for replacement of WebClient.

        ''' <summary>
        '''  Sends and receives a packet to and from the passed in Uri.
        '''  Maps older networkCredentials to HttpClientHandler.
        ''' </summary>
        ''' <param name="addressUri">Uri to the remote file.</param>
        ''' <param name="destinationFileName">Name and path of file where download is saved.</param>
        ''' <param name="networkCredentials">The credentials of the user performing the download.</param>
        ''' <param name="dialog">A ProgressDialog or Nothing.</param>
        ''' <param name="connectionTimeout">Time allotted before giving up on a connection.</param>
        ''' <param name="overwrite">Indicates whether or not the file should be overwritten if local file already exists.</param>
        ''' <param name="onUserCancel"></param>
        Friend Shared Function DownloadFileAsync(
            addressUri As Uri,
            destinationFileName As String,
            networkCredentials As ICredentials,
            dialog As ProgressDialog,
            connectionTimeout As Integer,
            overwrite As Boolean,
            onUserCancel As UICancelOption) As Task

        ''' <summary>
        '''  Downloads a file from the network to the specified path.
        ''' </summary>
        ''' <param name="addressUri">Uri to the remote file</param>
        ''' <param name="destinationFileName">Name and path of file where download is saved.</param>
        ''' <param name="userName">The name of the user performing the download.</param>
        ''' <param name="password">The user's password.</param>
        ''' <param name="dialog">A ProgressDialog or Nothing.</param>
        ''' <param name="connectionTimeout">Time allotted before giving up on a connection.</param>
        ''' <param name="overwrite">Indicates whether or not the file should be overwritten if local file already exists.</param>
        Friend Shared Async Function DownloadFileAsync(
            addressUri As Uri,
            destinationFileName As String,
            userName As String,
            password As String,
            dialog As ProgressDialog,
            connectionTimeout As Integer,
            overwrite As Boolean) As Task

        ''' <summary>
        '''  Downloads a file from the network to the specified path.
        ''' </summary>
        ''' <param name="addressUri">Uri to the remote file</param>
        ''' <param name="destinationFileName">Name and path of file where download is saved.</param>
        ''' <param name="userName">The name of the user performing the download.</param>
        ''' <param name="password">The user's password.</param>
        ''' <param name="dialog">ProgressDialog or Nothing.</param>
        ''' <param name="connectionTimeout">Time allotted before giving up on a connection.</param>
        ''' <param name="overwrite">Indicates whether or not the file should be overwritten if local file already exists.</param>
        ''' <param name="onUserCancel">Indicates what to do if user cancels dialog (either throw or do nothing).</param>
        Friend Shared Async Function DownloadFileAsync(
            addressUri As Uri,
            destinationFileName As String,
            userName As String,
            password As String,
            dialog As ProgressDialog,
            connectionTimeout As Integer,
            overwrite As Boolean,
            onUserCancel As UICancelOption) As Task

        ''' <summary>
        '''  Downloads a file from the network to the specified path.
        ''' </summary>
        ''' <param name="addressUri">Uri to the remote file</param>
        ''' <param name="destinationFileName">Name and path of file where download is saved.</param>
        ''' <param name="clientHandler">An HttpClientHandler of the user performing the download.</param>
        ''' <param name="dialog">Progress Dialog.</param>
        ''' <param name="connectionTimeout">Time allotted before giving up on a connection.</param>
        ''' <param name="overwrite">Indicates whether or not the file should be overwritten if local file already exists.</param>
        ''' <param name="onUserCancel">Indicates what to do if user cancels dialog (either throw or do nothing).</param>
        ''' <remarks>Calls to all the other overloads will come through here.</remarks>
        Friend Shared Async Function DownloadFileAsync(
            addressUri As Uri,
            destinationFileName As String,
            clientHandler As HttpClientHandler,
            dialog As ProgressDialog,
            connectionTimeout As Integer,
            overwrite As Boolean,
            onUserCancel As UICancelOption) As Task

        ''' <summary>
        '''  Downloads a file from the network to the specified path.
        ''' </summary>
        ''' <param name="address">Address to the remote file, http, ftp etc...</param>
        ''' <param name="destinationFileName">Name and path of file where download is saved.</param>
        ''' <param name="userName">The name of the user performing the download.</param>
        ''' <param name="password">The user's password.</param>
        ''' <param name="dialog">A ProgressDialog or Nothing.</param>
        ''' <param name="connectionTimeout">Time allotted before giving up on a connection.</param>
        ''' <param name="overwrite">Indicates whether or not the file should be overwritten if local file already exists.</param>
        Friend Shared Async Function DownloadFileAsync(
            address As String,
            destinationFileName As String,
            userName As String,
            password As String,
            dialog As ProgressDialog,
            connectionTimeout As Integer,
            overwrite As Boolean) As Task

        ''' <summary>
        '''  Downloads a file from the network to the specified path.
        ''' </summary>
        ''' <param name="address">Address to the remote file, http, ftp etc...</param>
        ''' <param name="destinationFileName">Name and path of file where download is saved.</param>
        ''' <param name="userName">The name of the user performing the download.</param>
        ''' <param name="password">The user's password.</param>
        ''' <param name="dialog">A ProgressDialog or Nothing.</param>
        ''' <param name="connectionTimeout">Time allotted before giving up on a connection.</param>
        ''' <param name="overwrite">Indicates whether or not the file should be overwritten if local file already exists.</param>
        ''' <param name="onUserCancel">Indicates what to do if user cancels dialog (either throw or do nothing).</param>
        Friend Shared Async Function DownloadFileAsync(
            address As String,
            destinationFileName As String,
            userName As String,
            password As String,
            dialog As ProgressDialog,
            connectionTimeout As Integer,
            overwrite As Boolean,
            onUserCancel As UICancelOption) As Task

        ''' <summary>
        '''  Downloads a file from the network to the specified path.
        ''' </summary>
        ''' <param name="addressUri">Uri to the remote file</param>
        ''' <param name="destinationFileName">Name and path of file where download is saved.</param>
        ''' <param name="networkCredentials">The credentials of the user performing the download.</param>
        ''' <param name="dialog">A ProgressDialog or Nothing.</param>
        ''' <param name="connectionTimeout">Time allotted before giving up on a connection.</param>
        ''' <param name="overwrite">Indicates whether or not the file should be overwritten if local file already exists.</param>
        ''' <remarks>
        '''  Function will Throw on unhandled exceptions.
        ''' </remarks>
        Friend Shared Async Function DownloadFileAsync(
            addressUri As Uri,
            destinationFileName As String,
            networkCredentials As ICredentials,
            dialog As ProgressDialog,
            connectionTimeout As Integer,
            overwrite As Boolean) As Task

API Usage

Dim t As Task = DownloadFileAsync(
  addressUri:=address,
  destinationFileName,
  networkCredentials,
  dialog,
  connectionTimeout,
  overwrite,
  onUserCancel)

Alternative Designs

Just a few Async API's with many optional parameters or exactly copy DownloadFile API's and make them all Async

Risks

There is already 100% test coverage in FixIssue#9807 PR so risk is minimal.

Will this feature affect UI controls?

No

paul1956 avatar Jul 24 '24 23:07 paul1956

@KlausLoeffelmann to investigate for .NET 10

merriemcgaw avatar Aug 07 '24 21:08 merriemcgaw

@KlausLoeffelmann they are all implemented as Friend and 100% tested in my Download PR though you probably want to make some changes in API to support a cancellation token.

paul1956 avatar Aug 08 '24 00:08 paul1956

@JeremyKuhne any chance of API review

paul1956 avatar Oct 11 '24 18:10 paul1956