如何在子线程结束后在主线程中运行一个方法?

时间:2021-12-04 21:01:16

I'm new with .Net Threads. I understand that we can't work with WinForm GUI out of the main thread. I want one of my method that update the WinForm GUI to run in the main thread right after a 2nd thread ends. Here is a part of my code:

我是.Net Threads的新手。据我所知,我们无法在主线程中使用WinForm GUI。我想要一个更新WinForm GUI的方法,在第二个线程结束后立即在主线程中运行。这是我的代码的一部分:

public class FormGApp : Form
{
    private Thread m_LoginThread;

    private void buttonLogin_Click(object sender, EventArgs e)
    {
        m_LoginThread = new Thread(new ThreadStart(this.login));                   
        m_LoginThread.Start();                 
    }

    private void login()
    {
        LoginResult result = loginToServer();
        this.User = result.LoggedInUser;
    }

    private void successfullyLogin()
    {
        // Update the WinForn GUI here...
        // This method must run in the main thread!!!
    }
}

How can I run the method successfullyLogin() when m_LoginThread ends?

当m_LoginThread结束时,如何运行successLogin()方法?

3 个解决方案

#1


3  

You have a couple of options:

你有几个选择:

  1. As @ScottChamberlain said in the comment, use a BackgroundWorker and use its Completed event to update the GUI

    正如@ScottChamberlain在评论中所说,使用BackgroundWorker并使用其Completed事件来更新GUI

  2. Use TPL Library in the following way:

    以下列方式使用TPL库:

    Task.Run(() => 
      {
        //do work
      }).ContinueWith(() => 
          {
              //do continuation
          }, TaskScheduler.FromCurrentSynchronizationContext);
    
  3. Use Application.Current.BeginInvoke or Application.Current.Invoke from your background thread

    从后台线程使用Application.Current.BeginInvoke或Application.Current.Invoke

#2


1  

If you are using .Net 4.5, you can use async/await

如果您使用的是.Net 4.5,则可以使用async / await

async private void buttonLogin_Click(object sender, EventArgs e)
{
    await Task.Run(() => login());
    successfullyLogin();
}

#3


0  

Thanks you all to inspire my to use BackgroundWorker, it indeed solved this issue. Here is my solution:

谢谢大家激励我使用BackgroundWorker,它确实解决了这个问题。这是我的解决方案:

public partial class FormGApp : Form
{
    private BackgroundWorker m_LoginBackgroundWorker;

    // ctor:
    public FormGApp()
    {
         // init thread:
         this.m_LoginBackgroundWorker = new BackgroundWorker();
         this.m_LoginBackgroundWorker.DoWork += this.LoginBackgroundWorker_DoWork;
         this.m_LoginBackgroundWorker.RunWorkerCompleted += this.LoginBackgroundWorker_RunWorkerCompleted;
    }

    private void buttonLogin_Click(object sender, EventArgs e)
    {
         // start thread:
         this.m_LoginBackgroundWorker.RunWorkerAsync();
    }

    private void LoginBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
         this.login();
    }

    private void LoginBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
         this.successfullyLogin();
    }

    private void login()
    {
         // code that take long time that executed in a separate thread... 
    }

    private void successfullyLogin()
    {
         // Gui WinForm update code here...
    }

#1


3  

You have a couple of options:

你有几个选择:

  1. As @ScottChamberlain said in the comment, use a BackgroundWorker and use its Completed event to update the GUI

    正如@ScottChamberlain在评论中所说,使用BackgroundWorker并使用其Completed事件来更新GUI

  2. Use TPL Library in the following way:

    以下列方式使用TPL库:

    Task.Run(() => 
      {
        //do work
      }).ContinueWith(() => 
          {
              //do continuation
          }, TaskScheduler.FromCurrentSynchronizationContext);
    
  3. Use Application.Current.BeginInvoke or Application.Current.Invoke from your background thread

    从后台线程使用Application.Current.BeginInvoke或Application.Current.Invoke

#2


1  

If you are using .Net 4.5, you can use async/await

如果您使用的是.Net 4.5,则可以使用async / await

async private void buttonLogin_Click(object sender, EventArgs e)
{
    await Task.Run(() => login());
    successfullyLogin();
}

#3


0  

Thanks you all to inspire my to use BackgroundWorker, it indeed solved this issue. Here is my solution:

谢谢大家激励我使用BackgroundWorker,它确实解决了这个问题。这是我的解决方案:

public partial class FormGApp : Form
{
    private BackgroundWorker m_LoginBackgroundWorker;

    // ctor:
    public FormGApp()
    {
         // init thread:
         this.m_LoginBackgroundWorker = new BackgroundWorker();
         this.m_LoginBackgroundWorker.DoWork += this.LoginBackgroundWorker_DoWork;
         this.m_LoginBackgroundWorker.RunWorkerCompleted += this.LoginBackgroundWorker_RunWorkerCompleted;
    }

    private void buttonLogin_Click(object sender, EventArgs e)
    {
         // start thread:
         this.m_LoginBackgroundWorker.RunWorkerAsync();
    }

    private void LoginBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
         this.login();
    }

    private void LoginBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
         this.successfullyLogin();
    }

    private void login()
    {
         // code that take long time that executed in a separate thread... 
    }

    private void successfullyLogin()
    {
         // Gui WinForm update code here...
    }