2016-01-26 5 views
0

Я работаю над программным обеспечением для передачи файлов. Но индикатор выполнения показывает 100% напрямую, не демонстрируя фактического прогресса. Так что мне нужно изменить мой метод для записи файла. Или есть глупая ошибка. Вот мой код. Form1.csиндикатор выполнения обновляется после достижения 100% в C#

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using System.Media; 
using System.Threading; 

namespace Sender2 
{ 

public partial class Form1 : Form 
{ 
    private Thread thrDownload; 
    private static int PercentProgress; 
    private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes); 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Browse_Click(object sender, EventArgs e) 
    { 
     if (openFileDialog1.ShowDialog() == DialogResult.OK) 
     { 
      txtSelectFilePath.Text = openFileDialog1.FileName; 
      String path1=txtSelectFilePath.Text; 
      files_list.Items.Add(path1); 
      files_list.View = View.List; 

     } 
    } 

    private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes) 
    { 

     PercentProgress = Convert.ToInt32((BytesRead * 100)/TotalBytes); 

     progressBar1.Value = PercentProgress; 

     lblProgress.Text = "Downloaded " + BytesRead + " out of " + TotalBytes + " (" + PercentProgress + "%)"; 
    } 


    private void Send_Click(object sender, EventArgs e) 
    { 
     TransferService2.TransferService2Client client = new TransferService2.TransferService2Client(); 

     foreach(ListViewItem item in files_list.Items) 
     { 
      TransferService2.File file = client.DownloadDocument(item.Text); 
      System.IO.FileStream fs = new System.IO.FileStream(@"c:\DownloadedFiles\" + file.Name, System.IO.FileMode.Create); 
Int64 fileSize = file.Content.Length; 
      int bytesSize = 0; 
      byte[] downBuffer = new byte[2048]; 
      int pos = 0; 
      int length = 128; 
      while (pos < file.Content.Length) 
      { 
       if (length > (file.Content.Length - pos)) 
       { 
        length = file.Content.Length - pos; 
       } 
       fs.Write(file.Content, pos, length); 
       this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { file.Content.Length, fileSize }); 
       pos = pos + length; 
      } 
      MessageBox.Show(file.Name + " is downloaded"); 

     } 

    } 






} 
} 

TransferService2.cs

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 

namespace TransferService2 
{ 
public class TransferService2 : ITransferService2 
{ 

    public File DownloadDocument(String filepath) 
    { 
     File file = new File(); 
     String path = filepath; 
     byte[] buffer; 
     FileStream fs = new FileStream(@path, FileMode.Open, FileAccess.Read); 
     try 
     { 
      int length = (int)fs.Length; 
      buffer = new byte[length]; 
      int count; 
      int sum = 0; 
      while((count=fs.Read(buffer,sum,length-sum))>0) 
      { 
       sum = sum + count; 
      } 
     } 
     finally 
     { 
      fs.Close(); 
     } 
     file.Content = buffer; 
     file.Name = Path.GetFileName(path); 
     return file; 
    } 
} 
} 

ITransferService2.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Runtime.Serialization; 
using System.ServiceModel; 
using System.Text; 

namespace TransferService2 
{ 

[ServiceContract] 
public interface ITransferService2 
{ 
    [OperationContract] 
    File DownloadDocument(String filepath); 
} 

[DataContract] 
public class File 
{ 
    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public byte[] Content { get; set; } 

} 
} 
+0

Похоже, вы выполняете все операции на потоке пользовательского интерфейса, поэтому он занят и не может обновлять во время обработки. Рассмотрим некоторые из асинхронных методов. –

+0

Можете ли вы предложить какую-либо технику или образец кода или обновить код выше –

ответ

0

Как я уже говорил в комментариях, вы выполняете всю операцию синхронно в потоке пользовательского интерфейса, поэтому он занят и не может обновляться во время обработки.

Необходимо выполнить операцию асинхронно. Есть много способов сделать это, вот один из возможных способов использования async/await:

private async void Send_Click(object sender, EventArgs e) 
{ 

    TransferService2.TransferService2Client client = new TransferService2.TransferService2Client(); 

    foreach(ListViewItem item in files_list.Items) 
    { 
     TransferService2.File file = await Task.Run(() => client.DownloadDocument(item.Text)); 
     System.IO.FileStream fs = new System.IO.FileStream(@"c:\DownloadedFiles\" + file.Name, System.IO.FileMode.Create); 
     Int64 fileSize = file.Content.Length; 
     int bytesSize = 0; 
     byte[] downBuffer = new byte[2048]; 
     int pos = 0; 
     int length = 128; 
     while (pos < file.Content.Length) 
     { 
      if (length > (file.Content.Length - pos)) 
      { 
       length = file.Content.Length - pos; 
      } 
      await fs.WriteAsync(file.Content, pos, length); 
      // Here the await will resume on the UI thread, so no Invoke is needed 
      pos = pos + length; 
      this.UpdateProgress(pos, fileSize); 
     } 
     MessageBox.Show(file.Name + " is downloaded"); 
    } 
} 
+0

Спасибо вам большое, сэр. Теперь он работает асинхронно. Но все же у меня есть некоторые проблемы, так как мои вычисления метода UpdateProgress ошибочны. это? Индикатор выполнения Coz обновляется, но не отображается в тексте lblProgress, поскольку я предоставляю это с использованием PercentProgress и всех. –

+0

@ShankyRedkar Я не смотрел на него, похоже, что вызов 'UpdateProgress' передавал одно и то же значение для обоих аргументов. Попробуйте обновленный код. –

+0

Сэр Ohhh Спасибо, очень сэр ... Он работает сейчас .... –

Смежные вопросы