0

I writing a WPF desktop application and I used async await to keep my UI update. its works OK for 5 or 6 sec but after that UI freezing but background code is running normally.

await Task.Run(() =>
{
    result = index.lucene_index(filepath, filename, fileContent);
    if (result) {
        updateResultTextBox(filename);
        Task.Delay(1000);
    }
});

and updateResultTextBox is

private void updateResultTextBox(string _filename)
{
    sync.Post(new SendOrPostCallback(o =>
    {
        result_tbx.Text += "Indexed \t" + (string)o + "\n";
        result_tbx.ScrollToEnd();
    }), _filename);
}
Rand Random
  • 7,300
  • 10
  • 40
  • 88
siavash
  • 1
  • 2
  • How are you calling that first block of code? – Camilo Terevinto Feb 02 '18 at 12:52
  • 1
    What is sync.Post? Please provide a minimal working example. https://stackoverflow.com/help/mcve – Marisa Feb 02 '18 at 12:52
  • @CamiloTerevinto in the button click you can see entire code in [github](https://github.com/siavashhsn/lucene-search-desktop-application/blob/master/search/Index.xaml.cs) line 230 – siavash Feb 02 '18 at 13:07
  • @Marisa I get it from (https://stackoverflow.com/a/12029045/1841364) – siavash Feb 02 '18 at 13:10
  • @Marisa and this site (https://stephenhaunts.com/2014/10/14/using-async-and-await-to-update-the-ui-thread/) – siavash Feb 02 '18 at 13:12
  • You should type out the question clearly. Something like: What in my code could cause the UI to freeze? Which part in the code should I pay attention to? – maxpaj Feb 02 '18 at 13:21
  • @maxpaj i am sorry my unclear question its my first time . – siavash Feb 06 '18 at 19:05

2 Answers2

0

Your question is less then clear. So I have to guess. My only guess at this time: GUI write overhead.

Writing the GUI is not cheap. If you only do it once per user triggered event, you do not notice it. But once you do it in a loop - even one that runs in a seperate task or thread - you will notice it. I wrote this simple Windows Forms example to showcase the difference:

using System;
using System.Windows.Forms;

namespace UIWriteOverhead
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int[] getNumbers(int upperLimit)
        {
            int[] ReturnValue = new int[upperLimit];

            for (int i = 0; i < ReturnValue.Length; i++)
                ReturnValue[i] = i;

            return ReturnValue;
        }

        void printWithBuffer(int[] Values)
        {
            textBox1.Text = "";
            string buffer = "";

            foreach (int Number in Values)
                buffer += Number.ToString() + Environment.NewLine;
            textBox1.Text = buffer;
        }

        void printDirectly(int[] Values){
            textBox1.Text = "";

            foreach (int Number in Values)
                textBox1.Text += Number.ToString() + Environment.NewLine;
        }

        private void btnPrintBuffer_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Generating Numbers");
            int[] temp = getNumbers(10000);
            MessageBox.Show("Printing with buffer");
            printWithBuffer(temp);
            MessageBox.Show("Printing done");
        }

        private void btnPrintDirect_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Generating Numbers");
            int[] temp = getNumbers(1000);
            MessageBox.Show("Printing directly");
            printDirectly(temp);
            MessageBox.Show("Printing done");
        }
    }
}

If you start a lot of those tasks and they suddenly all return 5-6 seconds in the process, you might just plain overload the GUI thread with the sheer amount of write operations.

I actually had that issue with my very first attempt at Multithreading. I did proper Multthreading, but I still overloaded the GUI thread wich made it appear I had failed.

Christopher
  • 9,634
  • 2
  • 17
  • 31
0

there is something very strange on this code. Anyway, here are my two cents:

var text = await Task.Run(() =>
{
    result = index.lucene_index(filepath, filename, fileContent);
    if (result) {
        return filename;
    }
    return string.Empty;
});
if (!string.IsNullOrEmpty(text)) {
    result_tbx.Text += $"Indexed \t {text} {Environment.NewLine}";
    result_tbx.ScrollToEnd();
}

Still a code smell...

Marco
  • 984
  • 10
  • 18