-1

执行流程:

  1. 从主线程我调用了新线程(并行线程),它正在执行一个长时间运行的过程。
  2. 并行线程正在更新主线程 UI。
  3. 我让我的主线程等到并行线程完成。
  4. 我需要两个线程之间的同步。
  5. 我需要在主线程中使用并行线程的结果,所以我阻塞了主线程,直到并行进程完成。

这是我的代码有问题,请提出解决问题的建议。

    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());

    }
4

3 回答 3

3

我让我的主线程等到并行线程完成。

在那里你封锁了自己。当初为什么要开新帖?保持 UI 响应。现在你无论如何都阻止了它。不要阻止它。我不知道你想在线程运行时做什么,可能会在线程完成时更改控制状态并重置它们,但你不想要的是阻塞你的 UI 线程。停下来,找到另一种方法来实现你想要实现的任何目标。

于 2015-01-02T12:08:31.800 回答
0

您似乎正在寻找一种在并行操作过程中报告 UI 进度并等待最终结果(同步)对其进行处理的方法。

这可以使用 轻松完成Async/Await,无需运行手动线程、同步构造或线程编组(用于 UI 调用),最重要的是无需阻塞 UI 线程。

这是一个如何运行并行操作、向 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";
}
于 2015-01-02T12:33:53.733 回答
0
 public delegate void Action();
    private void UpdateUI(object txt)
    {
        this.BeginInvoke((Action)(() =>
        {
            label2.Text = (string)txt;
        })); 
    }

通过使用这段代码,我们不需要等待另一个线程......

于 2015-01-02T12:09:25.213 回答