2014-04-12 107 views
1

我是新的.Net線程。我明白,我們無法在主線程中使用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!!! 
    } 
} 

如何運行的方法successfullyLogin()m_LoginThread結束?

+0

而不是使用'Thread'爲什麼不使用'BackgroundWorker'誰的「完成」事件在UI線程上運行的。 –

+0

最近的版本odf .net你正在使用 –

回答

0

感謝大家對我的啓發使用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... 
    } 
3

你有兩個選擇:

  1. 由於@ScottChamberlain中的評論稱,使用BackgroundWorker並使用其Completed事件來更新GUI

  2. 使用TPL Library以下列方式:

    Task.Run(() => 
        { 
        //do work 
        }).ContinueWith(() => 
         { 
          //do continuation 
         }, TaskScheduler.FromCurrentSynchronizationContext); 
    
  3. 使用Application.Current.BeginInvokeApplication.Current.Invoke FR OM你的後臺線程

1

如果您使用的是.NET 4.5,你可以使用異步/等待

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

我使用.Net 4.0,但重點是我不想等待。我希望主線程繼續工作。只有當子線程結束主線程時,才能成功執行該方法.Login() –

+0

@GilEpshtain問題是上面的代碼不會阻塞UI。 (順便說一句:'我不想等'.'是錯誤的,你想**等待**而不阻止用戶界面) –

相關問題