7

I am using function from a library to process really big word files and I can't change this function. While processing, I want to show a progress bar, because either way the app looks frozen and the users are not aware it's actually working. For now I'm using a worker like this:

private void btnClick(object sender, RoutedEventArgs e)
{ 
    BackgroundWorker worker = new BackgroundWorker();
    worker.RunWorkerCompleted += worker_RunWorkerCompleted;
    worker.WorkerReportsProgress = true;
    worker.DoWork += worker_DoConvertOne;
    worker.ProgressChanged += worker_ProgressChanged;
    worker.RunWorkerAsync();
}

private void worker_DoConvertOne(object sender, DoWorkEventArgs e)
{
    var worker = sender as BackgroundWorker;
        //The progress bar is filled on 20%
        worker.ReportProgress(0);
        worker.ReportProgress(10);
        worker.ReportProgress(20);

        //Processing
        myLongLastingFunction(bigWordFile);

        //The progress bas is full
        worker.ReportProgress(100, "Done Processing.");
}

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    MessageBox.Show("Converting finished!");
    TestProgressBar.Value = 0;
    ProgressTextBlock.Text = "";
}

private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    TestProgressBar.Value = e.ProgressPercentage;
    ProgressTextBlock.Text = (string)e.UserState;
}

It's doing the work, but it's a workaround and i want to know if there is a proper way to solve my problem. Thanks in advance. :)

nyagolova
  • 1,401
  • 2
  • 21
  • 37
  • 1
    Is your LongLastingFunction sends update? If not then you can use infinite progressbar. Hide it at completion – Satyaki Chatterjee Jan 27 '16 at 09:51
  • are you reading a file in `myLongLastingFunction`? What are you doing in `myLongLastingFunction`? – StepUp Jan 27 '16 at 10:04
  • @SatyakiChatterjee, no, it doesn't sends update. At least i don't think so.. So i really may consider using an infinite progressbar. – nyagolova Jan 27 '16 at 12:38
  • @StepUp - the function converts one file format to another. But the files are big and sometimes it takes about 10 sek .. And yes, it reads a file. – nyagolova Jan 27 '16 at 12:39

4 Answers4

3

I take from your question that altering the myLongLastingFunction is not possible to give you periodic updates on progress, and this ability currently does not exist in the function.

For these scenarios when the duration of the task cannot be determined then a progress bar with the dependency property IsIndeterminate="True" is the accepted way to give this information to the user. This animates the progress bar to be scrolling continuously.

XAML

   <ProgressBar Margin="10" IsIndeterminate="True" />

I personally prefer the animated moving dots as seen on Windows Phone. An example has been implemented here.

If this is not what you require the next best method is to estimate the total time, and subdividing this time with a DispatchTimer to give a periodic event to increment the progress bar. This obviously has two problems of either finishing before reaching 100% (not a bad thing) or reaching 100% and getting stuck there as the actual time is significantly longer than the estimate. The second undesired effect will make the application look inactive again.

Community
  • 1
  • 1
Rhys
  • 4,411
  • 2
  • 21
  • 32
  • Thanks for the answer, I may try with the Dispatcher and if doesn't work, will go with the infinite progressbar. :) – nyagolova Jan 27 '16 at 12:41
2

if you are using 4.5 then you can use IProgress. please refer this example [https://code.msdn.microsoft.com/Progress-of-a-Task-in-C-cdb179ee][1]

Joby James
  • 429
  • 7
  • 21
2

It is possible to show current progress by ProgressBar and BackgroundWorker when reading .txt(Word) files. You should just calculate proportion of how many 1 percent is for ProgressBar. Let's see work example:

Code behind:

public partial class MainWindow : Window
{
    BackgroundWorker bw;
    long l_file;
    public MainWindow()
    {
        InitializeComponent();
    }

    string fileName = "";
    private void InitializeBackgroundWorker()
    {   
        bw = new BackgroundWorker();
        bw.DoWork += Bw_DoWork;
        bw.ProgressChanged += Bw_ProgressChanged;            
        bw.WorkerReportsProgress = true;
    }



    private void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar.Value = e.ProgressPercentage;
    }

    private void Bw_DoWork(object sender, DoWorkEventArgs e)
    {
        ReadFile(fileName);
    }

    private void btnOpenFLD_Click(object sender, RoutedEventArgs e)
    {
        progressBar.Minimum = 0;
        progressBar.Maximum = 100;

        OpenFileDialog ofd = new OpenFileDialog();            
        if (ofd.ShowDialog() == true)
        {                
            FileInfo fileInfo = new FileInfo(ofd.FileName);
            l_file = fileInfo.Length;
            fileName = ofd.FileName;
            InitializeBackgroundWorker();
            bw.RunWorkerAsync();
        }            
    }        

    private void ReadFile(string fileName)
    {
        string line;
        long onePercent = l_file / 100;
        long lineLength = 0;
        long flagLength = 0;
        using (StreamReader sr = new StreamReader(fileName, System.Text.Encoding.ASCII))
        {
            while (sr.EndOfStream == false)
            {
                line = sr.ReadLine();
                lineLength = line.Length;
                flagLength += lineLength+2;
                //Thread.Sleep(1);//uncomment it if you want to simulate a 
                //very heavy weight file
                if (flagLength >= onePercent)
                {
                    CountProgressBar += 1;
                    bw.ReportProgress(CountProgressBar);
                    flagLength %= onePercent;
                }
            }
        }
    }

    int countProgressBar = 0;
    private int CountProgressBar
    {
        get { return countProgressBar; }
        set
        {
            if (countProgressBar < 100)
                countProgressBar = value;
            else
                countProgressBar = 0;
        }
    }
}    

XAML:

<Window x:Class="BackgroundWorkerProgressBarReadFile.MainWindow"
        ...The code omitted for the brevity...
        xmlns:local="clr-namespace:BackgroundWorkerProgressBarReadFile"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="0.2*"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>            
        </Grid.ColumnDefinitions>
        <ProgressBar Margin="5" Name="progressBar"/>
        <Button Grid.Row="1" Content="Open File Dialog" Name="btnOpenFLD"  
        Click="btnOpenFLD_Click"/>


    </Grid>
</Window>

If you do some other works after reading file and you want to show progress, then just move this code after all works you do.

if (flagLength >= onePercent)
{
    CountProgressBar += 1;
    bw.ReportProgress(CountProgressBar);
    flagLength %= onePercent;
}
StepUp
  • 27,357
  • 12
  • 66
  • 120
1

If your myLongLastingFunction is not reporting any progress, it is impossible to tell how much of its work is completed at any point.

However as Satyaki Chatterjee already suggested you can use an infinite progress bar.

wertzui
  • 3,673
  • 2
  • 26
  • 36