如何让主线程等到其他线程结束

时间:2014-06-11 09:44:34

标签: c# multithreading

我有一个方法:

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方法中放置断点,以检查它是否会被调用但是没有被击中。应用程序被卡在内部的infite循环中。

我可以做些什么来强制我的主线程等待线程并在委托调用时跳转到completeinstall方法?

@Update:

根据您的建议,我的代码如下所示:

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()行,它永远不会被击中。 而对于我的不明原因,DoProcessing之后会调用mre.WaitOne()。 Action和BeginInvoke是否也不同步?

3 个答案:

答案 0 :(得分:1)

您可以使用ManualResetEvent类。

创建ManualResetEvet

ManualResetEvent mre = new ManualResetEvent(false);

Main方法中等待此事件发出信号。

mre.WaitOne();

在你的代表中(当工作完成时),发出事件的信号。

mre.Set();

答案 1 :(得分:1)

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

然后您将对WaitOne进行阻止调用,直到您从另一个帖子中调用Set

答案 2 :(得分:1)

感谢您更新问题。 看起来你永远不会创建一个真正的新线程,即你正在挂起主线程并有效地使你的应用程序陷入僵局。

您可以在此处创建新的Thread

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