简体   繁体   中英

Application is not responding, when i tried to updated UI from another thread

Execution Flow:

  1. From main thread I invoked the new thread(Parallel thread), which is doing a long running process.
  2. Parallel thread is updating the main thread UI.
  3. I made my main thread to wait until parallel thread is complete.
  4. I need a synchronization between two thread.
  5. I need to use the result of parallel thread in main thread so I blocked main thread until parallel process complete.

Here is my code which is having issue, please give suggestion to resolve the issue.

    private readonly AutoResetEvent _resetEvent = new AutoResetEvent(false);
    private event EventHandler Workcompleted;

    private void button1_Click(object sender, EventArgs e)
    {
        Workcompleted += Completed;
        Thread thr = new Thread(UpdateUI);
        thr.Start("");

        _resetEvent.WaitOne();

         // Logical operation dependent on parallel process final result 

    }

    private void Completed(object sender, EventArgs args)
    {
        _resetEvent.Set();
    }

    private void UpdateUI(object txt)
    {
        for (int i = 0; i < 10; i++)
        {
            if (label1.InvokeRequired)
            {
                label1.Invoke(new ParameterizedThreadStart(UpdateUI), i.ToString());
            }
            else
            {
                label1.Text = (string)txt;
                Thread.Sleep(100);
            }
        }

        if (Workcompleted != null)
            Workcompleted(this, new EventArgs());

    }

I made my main thread to wait until parallel thread is complete.

And there you blocked yourself. Why did you start a new thread in the first place? To keep the UI responsive. And now your blocked it anyway. Do not block it. I don't know what you want to do while the thread is running, probably changing control states and resetting them when the thread is done, but what you don't want is blocking your UI thread. Stop that and find another way to achieve whatever you want to achieve.

 public delegate void Action();
    private void UpdateUI(object txt)
    {
        this.BeginInvoke((Action)(() =>
        {
            label2.Text = (string)txt;
        })); 
    }

By using this code, we don't need to wait for another thread...

It seems you are looking for a way to report progress in the UI during the course of the parallel operation and wait for the final result (synchronize) to do something with it.

This could easily be accomplished using Async/Await , without having to run manual threads, synchronization constructs or thread marshaling (for UI invocation) and most importantly without blocking the UI thread.

Here is an example of how to run a parallel operation, report progress back to the UI, update UI continuously and finally do something with the result when it is available.

private async void button1_Click(object sender, EventArgs e)
{
    var progress = new Progress<int>(ShowProgressInUi);
    var result = await Task.Run(() => DoParallelWorkAsync(progress));

    // Do something with final result
    label1.Text = result;
}

private void ShowProgressInUi(int progress)
{
    label1.Text = string.Format("Progress: {0} % done...", progress);
}

private static async Task<string> DoParallelWorkAsync(IProgress<int> progress)
{
    // This work is done in a separate thread.
    // In this case a background thread (from the thread pool),
    // but could be run on a foreground thread if the work is lengthy.
    for (var i = 1; i <= 10; i++)
    {
        // Simulate workload
        await Task.Delay(100);
        progress.Report(i * 10);
    }

    return "All done";
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM