0

I am working on xamarin.forms application. I want to download multiple files simultaneously using HttpClient. If there is multiple files then I am getting : System.IO.IOException:Sharing violation on path . Is there anything that has to be improved ? Here is my code for downloading files :

    public async Task DownloadFileAsync(string sourceUrl, string filePathWhereToSave, CancellationTokenSource cts)
    {
        Exception error = null;
        bool isCancelled = false;            
        try
        {
            if (!downloadingTasks.ContainsKey(sourceUrl))
                downloadingTasks.Add(sourceUrl, cts);

            var token = cts.Token;
            var response = await _client.GetAsync(sourceUrl, HttpCompletionOption.ResponseHeadersRead, token);
            response.EnsureSuccessStatusCode();

            string fileName = filePathWhereToSave.Substring(filePathWhereToSave.LastIndexOf('/'));
            string directory = filePathWhereToSave.Substring(0, filePathWhereToSave.LastIndexOf('/'));
            if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
                Directory.CreateDirectory(directory);

            var totalData = response.Content.Headers.ContentLength.GetValueOrDefault(-1L);
            var canSendProgress = totalData != -1L;

            await Task.Run(async() =>
            {
                using (var fileStream = OpenStream(filePathWhereToSave))
                {
                    using (var stream = await response.Content.ReadAsStreamAsync())
                    {
                        var totalRead = 0L;
                        var buffer = new byte[bufferSize];
                        var isMoreDataToRead = true;

                        do
                        {
                            var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);

                            if (read == 0)
                                isMoreDataToRead = false;
                            else
                            {
                                await fileStream.WriteAsync(buffer, 0, read);

                                totalRead += read;

                                if (canSendProgress)
                                {
                                    //var progress = ((totalRead * 1d) / (totalData * 1d) * 100);
                                    MessagingCenter.Send<DownloadFileProgressChangedMessage>(new DownloadFileProgressChangedMessage(sourceUrl, totalRead, totalData, 0), MessageNameConstants.DownloadFileProgressChangedMessage);
                                }
                            }
                        } while (isMoreDataToRead);
                    }
                }
            });
        }
        catch (OperationCanceledException ex)
        {
            isCancelled = true;
        }
        catch (Exception e)
        {
            error = e;
            System.Diagnostics.Debug.WriteLine(e.ToString());                
        }
        finally
        {
            MessagingCenter.Send<DownloadCompletedMessage>(new DownloadCompletedMessage(sourceUrl, filePathWhereToSave, error, isCancelled), MessageNameConstants.DownloadCompletedMessage);

            if (downloadingTasks.ContainsKey(sourceUrl))
                downloadingTasks.Remove(sourceUrl);
        }
    }       
Dhruv Gohil
  • 503
  • 1
  • 5
  • 13
  • Where is the error being raised? How are you getting multiple files? Your code only has a single file (i.e. `string filePathWhereToSave`). – Enigmativity Jun 19 '20 at 03:01
  • @Enigmativity e.g. I have two files and both have download buttons, If I click both button at the same time or one after another immediately , it starts downloading both files. and sometimes I get System.IO.IOException:Sharing violation on path at fileStream.WriteAsync(buffer, 0, read); – Dhruv Gohil Jun 19 '20 at 03:37
  • Can you provide code that simulates the situation where you get this error? – Enigmativity Jun 19 '20 at 04:24
  • This question seems relevant https://stackoverflow.com/questions/11541244/sharing-violation-ioexception-while-reading-and-writing-to-file-c-sharp. But your code doesn't show where that can happen. You need to post a [mcve] please. – Enigmativity Jun 19 '20 at 05:50

1 Answers1

0

This may be happening because the file is being locked by the reading stream, so the writing stream can't be created and you get the exception.

To avoid it you could enable read/write access with the class FileStream .

  FileStream fileStream = new FileStream(filePathWhereToSave,
                                   FileMode.OpenOrCreate,
                                   FileAccess.ReadWrite,
                                   FileShare.None);

Or use StreamWriter

using (var writer = new StreamWriter(filePathWhereToSave))
{
   // do work here.
}

BTW , what is OpenStream ? I can't find it in any assembly, is it included in a third-party library ?


Refer to

https://stackoverflow.com/a/23779697/8187800

https://stackoverflow.com/a/11541330/8187800

ColeX
  • 14,062
  • 5
  • 43
  • 240
  • Hi ,have you solved the problem or not ? ?If you have any other question , feel free to let me know . – ColeX Jun 26 '20 at 05:18