-1

I have simple task in my app, but i have problem.

For example:

for (int i = 1; i <= 1000000; i++)
{
    if (i % 2 == 0) {       
        TextBlock.Text += string.Format("{0},", i);
    }
}

While app doing that task it takes long time, so I would like it displays number when it is found and not at the end, all numbers together. What is the simplest way to do that for newbie like me? It is WP8, C#.

Thanks a lot.

xsami
  • 1,312
  • 16
  • 31
Toni0123
  • 107
  • 1
  • 11
  • Somehow I doubt that you really want to print out 500,000 numbers to the screen as fast as you possibly can. I can't imagine how that would be useful to a user, and it'd certainly lock up the screen for quite some time while you try to write them all out. – Servy Apr 02 '15 at 17:28
  • I am not trying to display all those number, it is just example, my app will display few numbers but calculation takes long time, and UI freezes. – Toni0123 Apr 02 '15 at 17:31
  • So basically `TextBlock.Text += string.Format("{0},", i);` doesn't do anything, until loop is finished? Thats because UI gets repainted only **after** code behind stops executing. – Yura Apr 02 '15 at 17:32
  • Then come up with an example that more closely resembles your situation. In this example computing the data takes basically no time at all, and the problems stem from the *amount* of data that you have. Display a small result from a long running computation is a *much* simpler problem to solve. – Servy Apr 02 '15 at 17:32
  • Ok, lets say I need as I have wrote in first post. I need to display 500,000 numbers one by one. – Toni0123 Apr 02 '15 at 17:34

3 Answers3

0

you can keep adding these numbers in a queue object and have a thread looking for a change in the queue object and simultaneously update the textbox.

Sushil
  • 2,837
  • 4
  • 21
  • 29
0

So the problem is, that UI doesn't get refreshed until your loop end, even if you are appending text to TextBox. The easy way to fix it - is to add Application.DoEvents() call after TextBlock.Text += string.Format("{0},", i);. But it has some critical downsides (explained here https://stackoverflow.com/a/5183623/2152334).

The right way is to do calculation in a different thread (using Tasks for example) and update UI thread using Dispatcher:

Deployment.Current.Dispatcher.BeginInvoke(() =>
{
   TextBlock.Text += ...
});
Community
  • 1
  • 1
Yura
  • 2,013
  • 19
  • 25
0

You can't refresh the display if your code blocks the UI thread. You need to leave the UI thread for your long task.

// We go to a non-UI thread
TaskEx.Run(() => {
    for (int i = 1; i <= 1000000; i++)
    {
        // some long operation here... -_-"
        if (i % 2 == 0)
        {
            // We return to UI thread after long operation to display the result
            Deployment.Current.Dispatcher.InvokeAsync(() => {
                TextBlock.Text += string.Format("{0},", i);
            });
        }
    }
});

Also you might consider adding a cancellation token to break the loop in case the user leaves the page being displayed.

[edit: this solution is meant for your comment "my app will display few numbers but calculation takes long time". If you really need 1000000 results, try to Dispatcher.InvokeAsync(...) and TextBlock.Text += ... multiple results at a time.]

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • That's just going to freeze the UI thread with the half a million scheduled invokes. – Servy Apr 02 '15 at 19:12
  • it won't freeze, but certainly will perform really slow, depending on machine. – Yura Apr 02 '15 at 19:14
  • I quote Toni0123: "*my app will display few numbers but calculation takes long time*". So there won't be this many numbers and this code should do. Otherwise, he can concat a few results together and batch display them 20 by 20. – Cœur Apr 02 '15 at 19:20
  • @Yura It will prevent any UI events from being handled besides these, until they're all done (which is likely to take some time). So yes, it'd freeze. – Servy Apr 02 '15 at 19:26
  • @Servy not true. Remember, we are talking about long operations, not just this `if (i % 2 == 0)` – Cœur Apr 02 '15 at 19:44
  • @Cœur Not according to the question being asked here. – Servy Apr 02 '15 at 19:45
  • Thanks guys for your help. It still blocks UI but your suggestions are helpful. Thanks – Toni0123 Apr 02 '15 at 20:50