2011-11-16 57 views
0

我有一個帶有文本「加載」的標籤的窗體。線程isAlive後的事件

label1.Text = "Loading..."; 

在Form.Load我有一個是做一些新的主題,可以說這一點。

void Form_Load(object sender, EventArgs args) 
{ 
    Thread t = new Thread(run); 
    t.Start(); 
} 

void run() 
{ 
    for(int i = 0; i < 1000000; i++) 
    { 

    } 
} 

我想要的主題「T」完成後更改label1.Text屬性設置爲「完成」。但是,在哪裏以及如何改變,我不知道。我正在學習線程。我是否必須創建一個線程來執行此操作,它會不斷檢查線程「t」的isAlive屬性?

+0

從'Task'切換到'BackgroundWorker'不是更簡單嗎? – Oliver

回答

2

您有多種解決方案。如果你真的想使用Thread類,你可以調用Join方法,但是這會阻塞UI線程,這不是一件好事。你也可以打電話給你的窗體的Invoke方法你之後「for」循環爲使

void run() 
{ 
    for (int i = 0; i < 100000000; i++) 
    { 
    } 

    this.Invoke(new Action(() => this.label1.Text = "done")); 
} 

,因爲你是在Windows窗體和invoke方法會在UI線程上執行代碼的調用方法是必需的。

除了使用Thread類之外,您還可以查看Delegate.BeginInvoke和System.Threading.Tasks。由於它彙集了線程和提供的回調來分離您的拆分代碼,因此它們更高效。

+1

這是一個真實的可怕解決方案,作爲形式和線程最終被緊密耦合。如果樣本基於我的問題, –

0

可能最容易做的事情是讓run在事件完成時引發一個事件,並讓表單附加一個處理程序來處理此事件。

+0

你可以發表一些代碼,這個 – Sandy

0

傳遞給標籤的引用或構成對你的線程,並使用Invokelabel1.Text="Completed"

1

容易

void run() 
{ 
    for(int i = 0; i < 1000000; i++) 
    { 

    } 

    Invoke(new MethodInvoker(delegate() 
             { 
              label1.Text = "finished"; 

             })); 
} 

或你提出一個事件,但在這樣一個簡單的例子這並不重要

+0

我害怕,但它不工作 – Sandy

+0

什麼不工作?我有相同的代碼,它的工作原理... :-) –

+0

真的很抱歉,它的工作....忘了更改標籤名稱... + 1 – Sandy

1

看看.NET4自帶的TPL Task Parallel Library。這使您有機會輕鬆啓動後臺工作程序,並定義在第一個任務完成後啓動的另一個任務。真正聰明的是,第二個任務(和其他任務一樣)可以配置爲在UI線程上運行,這樣就不必在任務操作中進行切換。

像這裏的小樣本:

var task = new Task(() => 
{ 
    // DoSomething very long in background 
}).ContinueWith(previousTask => 
    { 
     // Do some action on UI thread 
    }, 
    TaskScheduler.FromCurrentSynchronizationContext()); 

task.Start(); 
+0

會很感激,所以我對此有了更深入的瞭解。網上或文章上的任何相關示例也是可觀的。謝謝。我從來沒有聽說過它。 – Sandy

+0

@rapsalands:已被添加:-) – Fischermaen

+0

偉大的....如果可能的話再次投票 – Sandy

3

如果你的任務是真正做在另一個線程的東西,結果發佈到GUI,你應該在BackgroundWorker類看一看。

如果這對您不可行,您可以看看threading article of Joe。它應該真的回答你關於線程的所有問題。

如果您需要後臺工作人員的進一步幫助,只需在網上進行搜索或在SO上進行搜索即可。 Here is one of my answers,顯示如何使用後臺工作人員。

1

如果您願意使用Async CTP提議的asyncawait關鍵字,那麼這是一個邪惡的酷解決方案。

public async void Form_Load(object sender, EventArgs args) 
{ 
    label1.Text = "Loading..." 
    // Do some more stuff here if necessary. 
    label1.Text = await Run(); 
} 

private Task<string> Run() 
{ 
    var tcs = new TaskCompletionSource<string>(); 
    Task.Factory.StartNew(
    () => 
    { 
     for (int i = 0; i < 1000000; i++) 
     { 
     } 
     tcs.SetResult("Finished"); 
    }); 
    return tcs.Task; 
}