简体   繁体   English

当我尝试从另一个线程更新UI时,应用程序没有响应

[英]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. 并行线程正在更新主线程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. 保持UI响应。 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. 我不知道线程正在运行时想要做什么,可能更改了控制状态并在线程完成后将其重置,但是您不想要的是阻塞UI线程。 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. 似乎您正在寻找一种在并行操作过程中报告UI进度并等待最终结果(同步)对其进行处理的方法。

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. 这可以使用Async/Await轻松完成,而不必运行手动线程,同步构造或线程封送处理(用于UI调用),最重要的是无需阻塞UI线程。

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. 这是一个示例,说明如何运行并行操作,向UI报告进度,连续更新UI,以及在可用时最终对结果进行一些处理。

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";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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