2016-09-04 2 views
-2

Я пытаюсь реализовать ProgressBar, который будет отображаться во время передачи файла.Значение ProgressBar меняется, но gui не меняется на WPF

Передача файла осуществляется с помощью BackgroundWorker.

Просто чтобы проверить функциональность, я попытался добиться прогресса из основного потока, и ничего не происходит.

Код:

myProgressBar.Minimum = 0; 
myProgressBar.Maximum = numOfPackets; 

Вот код фона рабочий ...

, а затем:

myProgressBar.IsEnabled = true; 

for (int i = 0; i < buff.Length; i++) 
{ 
    myProgressBar.Value = i; 
    myProgressBar.UpdateDefaultStyle(); 
} 

Почему ничего не меняется?

+0

Вы уверены, что 'buff.Length' больше нуля? Итак, 'numOfPackets'? – Yakuza

ответ

0

Это очень плохо делать IO или файл передачи на фоновом потоке, потому что во время передачи файлов или IO работы процессора не привыкают так что ваш фоновый поток ничего не делает но ждут ввода-вывода, и вы тратите впустую один поток, который, в свою очередь, приводит к потерям памяти. Еще один недостаток заключается в том, что ваш пользовательский интерфейс перестанет реагировать на передачу файлов, занимает значительное количество времени, даже если вы делаете это на фоновом потоке.

Я могу продолжать писать недостатки, связанные с выполнением IO работы с фоновым потоком, но вы должны запросить одну документацию по асинхронному выполнению IO. Фоновые потоки предназначены для интенсивной работы с ЦП, например, для тяжелых вычислений, в которых задействован процессор.

Вы должны использовать асинхронный ввод-вывод. Используйте async и ждите. Пожалуйста, прочитайте об асинхронном IO. У меня есть один пример примера того, что вы делаете с чистым асинхронным IO с progressbar и отзывчивым интерфейсом. Я напишу это завтра.

** Ниже asynchronus И.О. кода передачи файлов, предполагая, что все файлы имеют одинакового размера для прогресса Updation нижеуказанного кода будет работать и приложений не будет висеть, даже при перемещении окна в то время как файлы проходят transffered. **

MainWindow.xaml

<Window x:Class="asyncawait.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="514" Width="674"> 
    <Grid Margin="0,0,0,4"> 
     <ScrollViewer Name="scrv_Log" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" HorizontalAlignment="Left" Width="397" Margin="33,61,0,67"> 
      <ListBox VirtualizingPanel.VirtualizationMode="Recycling" ItemsSource="{Binding Datas,Mode=OneWay}" Background="White" Foreground="Red"/> 
     </ScrollViewer> 
     <TextBlock Height="40" Width="70" FontSize="10" Foreground="Green" Text="{Binding FileCounter,Mode=OneWay}" Margin="540,281,56,158"></TextBlock> 
     <Button Foreground="Black" IsEnabled="{Binding IsButtonEnabled}" Click="Button_Click" Height="40" Width="40" RenderTransformOrigin="4.65,0.425" Margin="540,210,86,229"></Button> 
     <ProgressBar Value="{Binding Progressvalue,Mode=OneWay}" Name="prg" Foreground="Green" Height="20" Width="600" Margin="23,453,44.2,7"></ProgressBar> 
     <Label Content="{Binding ElementName=prg,Path=Value}" ContentStringFormat="{}{0}%" Height="25" Margin="253,0,295.2,22" VerticalContentAlignment="Center" VerticalAlignment="Bottom"/> 
     <TextBox Background='AliceBlue' HorizontalAlignment="Left" Height="23" Margin="525,109,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="97"/> 
    </Grid> 
</Window> 

**** Вот код, за который делает asynnchronous IO **

public partial class MainWindow: Window,INotifyPropertyChanged 
    { 

     public MainWindow() 
     { 
      InitializeComponent(); 
      this.DataContext = this; 
     } 
     public double Progressvalue 
     { 
      get 
      { 
       return _Progressvalue; 

      } 
      set 
      { 
       if(value!=_Progressvalue) 
       { 
        _Progressvalue=value; 
        OnPropertyChanged(); 
       } 
      } 
     } 
     private Double _Progressvalue=0; 
     private bool _IsEnabled=true; 

     public Boolean IsButtonEnabled { 
      get 
      { 
       return _IsEnabled; 
      } 

      set 
      { 
       if(value!=_IsEnabled) 
       { 
        _IsEnabled = value; 
        OnPropertyChanged(); 
       } 
      } 
     } 
     private async void Button_Click(object sender, RoutedEventArgs e) 
     { 
      IsButtonEnabled = false; 
      await AsyncTransferFiles(); 
      IsButtonEnabled = true; 
      scrv_Log.ScrollToBottom(); 

     } 

     private String fileCounter; 
     public String FileCounter 
     { 
      get 
      { return fileCounter; } 
      set 
      { 
       if (value != fileCounter) 
       { 
        fileCounter = value; 
        OnPropertyChanged(); 
       } 
      } 
     } 







     private ObservableCollection<String> _Datas = new ObservableCollection<string>(); 
     public ObservableCollection<String> Datas 
     { 
      get 
      { 
       return _Datas; 
      } 
     } 
     private async Task AsyncTransferFiles() 
     { 

      var fileNames = Directory.GetFiles("C:\\Data1").ToList(); 
      int totalCount = fileNames.Count; 
      pr = (double)1/totalCount; 
      int counter = 0; 
      var progress = new Progress<double>(); 
      progress.ProgressChanged += (sender, e) => 
       { 

        Progressvalue = Double.Parse(e.ToString()); 

       }; 
      foreach (var fileName in fileNames) 
      { 
       await (CopyFileAsync(fileName, "C:\\GradebookTemp1\\" + fileName.Split('\\')[2], progress, ++counter)); 
      } 
     } 



     double pr = 0.0; 
     public async Task CopyFileAsync(string sourcePath, string destinationPath,IProgress<double> progress ,int fileCounter) 
     { 
      using (Stream source = File.Open(sourcePath,FileMode.Open)) 
      { 
       using (Stream destination = File.Create(destinationPath)) 
       { 
        await source.CopyToAsync(destination); 
        progress.Report((int)(pr*fileCounter*100)); 
        FileCounter = fileCounter.ToString(); 
        Datas.Add("Copied File: " + sourcePath); 
        scrv_Log.ScrollToBottom(); 

       } 
      } 

     } 

     private void EnableButton() 
     { 
      IsButtonEnabled = true; 
     } 

     private void OnPropertyChanged([CallerMemberName] String propertyName=null) 
     { 
      var handler = PropertyChanged; 
      if(null!=handler) 
      { 
       handler(this, new PropertyChangedEventArgs(propertyName)); 

      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
    } 
+0

Большое спасибо за ваше руководство! я буду смотреть на задачи async/wait, я с нетерпением жду примера, который вы дадите, большое спасибо! Я хочу реализовать наилучшую практику с помощью моего кода. –

+0

asynchranous io код перевода добавлен – iaminvinicble

+0

спасибо! Я попробую это –

0

Для МОФ вы можете использовать это:

this.Dispacher.BeginInvoke(new Action(()=> { for(int i...)...; })); 
+0

Он сказал, что он уже запускает код в потоке пользовательского интерфейса. – Servy

0

Это решение работает один раз для меня:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void button_Click(object sender, RoutedEventArgs e) 
    { 
     for (int i = 0; i < 100; i++) 
     { 
      progBar.Value = i; 
      progBar.Refresh(); 
      Thread.Sleep(10); 
     } 
    } 

} 

public static class ExtensionMethods 
{ 
    private static Action EmptyDelegate = delegate() { }; 

    public static void Refresh(this UIElement uiElement) 
    { 
     uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate); 
    } 
} 

My associat изд-пример XAML в основном содержит:

<Grid> 
    <ProgressBar x:Name="progBar" HorizontalAlignment="Left" Height="10" Margin="116,175,0,0" VerticalAlignment="Top" Width="100"/> 
    <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="156,51,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/> 

</Grid> 

Но я думаю, что это еще не даже необходимо для понимания - я думаю, вы получите точку кода, это вполне самоописываемыми

+0

попробовал, хорошо работает только в новом окне. в моем приложении жестко он все еще не двигается –

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