Simple file copy example using BackgroundWorker class.

public class FileAsyncCopy
{
    private string _source;
    private string _target;
    BackgroundWorker _worker;
    public FileAsyncCopy(string source, string target)
    {
        if (!File.Exists(source))
            throw new FileNotFoundException(string.Format(@"Source file was not found. FileName: {0}", source));

        _source = source;
        _target = target;
        _worker = new BackgroundWorker();
        _worker.WorkerSupportsCancellation = false;
        _worker.WorkerReportsProgress = true;
        _worker.DoWork += DoWork;
    }


    private void DoWork(object sender, DoWorkEventArgs e)
    {
        int bufferSize = 1024*512;
        using(FileStream inStream = new FileStream(_source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        using (FileStream fileStream = new FileStream(_target, FileMode.OpenOrCreate, FileAccess.Write))
        {
            int bytesRead = -1;
            var totalReads = 0;
            var totalBytes = inStream.Length;
            byte[] bytes = new byte[bufferSize];
            int prevPercent = 0;

            while ((bytesRead = inStream.Read(bytes, 0, bufferSize)) > 0)
            {
                fileStream.Write(bytes, 0, bytesRead);
                totalReads += bytesRead;
                int  percent = System.Convert.ToInt32(((decimal)totalReads / (decimal)totalBytes) * 100);
                if (percent != prevPercent)
                {
                    _worker.ReportProgress(percent);
                    prevPercent = percent;
                }
            }
        }
    }

    public event ProgressChangedEventHandler ProgressChanged
    {
        add { _worker.ProgressChanged += value; }
        remove { _worker.ProgressChanged -= value; }
    }

    public event RunWorkerCompletedEventHandler Completed
    {
        add { _worker.RunWorkerCompleted += value; }
        remove { _worker.RunWorkerCompleted -= value; }
    }
    public void StartAsync()
    {
        _worker.RunWorkerAsync();
    }
}


// Usage
public class Usage
{
  public void Start()
  {
    FileAsyncCopy copy = new FileAsyncCopy(@"c:\a.dat", @"c:\b.dat");
    copy.Completed += CopyCompleted;
    copy.ProgressChanged += CopyProgressChanged;
    copy.StartAsync();
  }
  private void CopyCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
  {
    BackgroundWorker worker = sender as BackgroundWorker;
    worker.Dispose();
    // do something
  }

  private void CopyProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
  {
    // change progress bar or whatever
  }
}