title: Web Service file transfer, how to add retries?
body: <p>I have a bit of code that uses a Task to transfer a file over a web service. However if the network drops or a timeout occurs it results in an incomplete file. I'm really trying to make this service as reliable as possible, but I'm not really sure where to even really start to add code that will trap when a chunk was not sent, and then attempt to resend it multiple times but also not send the next chunk until that is done. And maybe if it cannot resend that chunk over X times, fail completely and log an event. </p>
  
  <p>Can anyone suggest anything?</p>
  
  <pre><code>Action&lt;Guid, string&gt; action = (smGuid, pubAttFullPath) =&gt;
          {
              try
              {
                  //Set filename from object
                  string FileName;
                  FileName = System.IO.Path.GetFileName(pubAttFullPath.ToString());
  
                  //Declare Web Service
                  TransferFile.TransferFileSoapClient ws_TransferFile = new TransferFile.TransferFileSoapClient();
  
                  //
                  bool transfercompleted = false;
                  using (FileStream fs = new FileStream(
                       pubAttFullPath.ToString(),
                       FileMode.Open,
                       FileAccess.Read,
                       FileShare.Read))
                  {
                      //Declare Buffers and Counts
                      byte[] buffer = new byte[49152];
                      long fileSize = fs.Length;
                      long totalReadCount = 0;
                      int readCount;
                      float percentageComplete = 0;
  
                      //Loop and copy file until it changes to not exactly the same byte count as the buffer
                      //which means the file is about to complete.
                      while ((readCount = fs.Read(buffer, 0, buffer.Length)) &gt; 0)
                      {
                          if (!transfercompleted)
                          {
  
                              totalReadCount += readCount;
                              byte[] bytesToTransfer;
  
                              if (readCount == buffer.Length)
                              {
                                  //Copy bytes until buffer is different
                                  bytesToTransfer = buffer;
                                  ws_TransferFile.WriteBinaryFile("ABCD", bytesToTransfer, FileName);
                                  percentageComplete = (totalReadCount / (float)fileSize * 100);
                                  percentageComplete = (float)Math.Round(percentageComplete, 2, MidpointRounding.ToEven);
                                  //Update progress to DB
  
                                  InsertProgress.InsertProgressSoapClient ws_InsertProgress = new InsertProgress.InsertProgressSoapClient();
                                  if (percentageComplete == 10.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 10.0);
                                  }
                                  if (percentageComplete == 20.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 20.0);
                                  }
                                  if (percentageComplete == 30.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 30.0);
                                  }
                                  if (percentageComplete == 40.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 40.0);
                                  }
                                  if (percentageComplete == 50.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 50.0);
                                  }
                                  if (percentageComplete == 60.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 60.0);
                                  }
                                  if (percentageComplete == 70.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 70.0);
                                  }
                                  if (percentageComplete == 80.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 80.0);
                                  }
                                  if (percentageComplete == 90.00)
                                  {
                                      ws_InsertProgress.InsertProgressService(smGuid.ToString(), 90.0);
                                  }
                              }
                              else
                              {
                                  // Only a part is requred to upload,
                                  // copy that part.
                                  List&lt;byte&gt; b = new List&lt;byte&gt;(buffer);
                                  bytesToTransfer = b.GetRange(0, readCount).ToArray();
                                  ws_TransferFile.WriteBinaryFile("ABCD", bytesToTransfer, FileName);
                                  percentageComplete = 100;
  
                                  //Insert Progress as complete
                                  InsertProgress.InsertProgressSoapClient ws_InsertProgress = new InsertProgress.InsertProgressSoapClient();
                                  ws_InsertProgress.InsertProgressService(smGuid.ToString(), 100);
                                  transfercompleted = true;
                                  fs.Close();
                                  break;
                              }
                          }
                      }
                  }
              }
              catch (Exception ex)
              {
                  EventLog.WriteEntry("Application", ex.Message.ToString(), EventLogEntryType.Error);
              }
  </code></pre>