如何使主线程等待其他线程结束

本文关键字:线程 结束 其他 等待 何使主 | 更新日期: 2023-09-27 18:08:01

我有一个方法:

public void Run()
{
    instalProgressPageViewModel.ExecuteButton_Click();
    //waiting here
    Environment.Exit(0);
}

方法Execute_Click()调用msi包的安装程序。这些安装程序在单独的线程中运行:

this.uiDispatcher.BeginInvoke(
            System.Windows.Threading.DispatcherPriority.Normal,
            new InstallationCompleted(this.completeInstallDelegate),
            installationState);

地点:

this.completeInstallDelegate // method which should be called after the thread is done.

等待功能CompleteInstall是至关重要的,因为它完成安装并开始安装包列表中的下一个msi包。

Run方法的示例代码中,app在任何事情发生之前被关闭。我试着输入:

while(true){}

// waiting here的位置,并在CompleteInstall方法中放置断点,以检查是否会调用它,但它没有被击中。应用程序在while内陷入无限循环。

我能做些什么来强迫我的主线程等待线程和跳入completeinstall方法时,委托调用?

@Update:

根据你的建议,我的代码看起来像这样:

there is

public static ManualResetEvent mre // global object initialized in main 

和其他类是:

public void Run()
{    
    instalProgressPageViewModel.ExecuteButton_Click();
    mre.WaitOne();
    Environment.Exit(0);
}

ExecuteButton_Click调用此函数:

    public void StartProcessing()
    {
        var processor = new Action(this.DoProcessing);
        processor.BeginInvoke(null, null);
    }
现在DoProcessing:

private void DoProcessing()
    {
        var installationState = this.Execute();
        // Schedule the update function in the UI thread.
        this.uiDispatcher.BeginInvoke(
            System.Windows.Threading.DispatcherPriority.Normal,
            new InstallationCompleted(this.completeInstallDelegate),
            installationState);
    }

和最后的completeInstallDelegate

private void CompleteInstall(InstallationState installationState)
    {
        App.mre.Set();
        /* 
         Some code
         */
        this.PostInstallAndNext();
    }

如果我把断点放在App.mre.Set()行,它永远不会被击中。由于我不知道的原因,DoProcessingmre.WaitOne()的名字命名。Action和BeginInvoke也不同步吗?

如何使主线程等待其他线程结束

感谢您更新问题。看起来你从来没有创建一个真正的新线程,也就是说,你挂起了主线程,有效地死锁了你的应用程序。

你可以创建一个新的Thread:

public void StartProcessing()
{
    var thread = new Thread(() => this.DoProcessing);
    thread.Start();
}

您可以使用ManualResetEvent类。

创建ManualResetEvet

ManualResetEvent mre = new ManualResetEvent(false);

Main方法中等待此事件获得信号。

mre.WaitOne();

在委托中(当工作完成时),发出事件信号。

mre.Set();

一个简单的解决方案是使用ManualResetEvent

你将有一个阻塞调用WaitOne,直到你从另一个线程调用Set