2011-11-16 48 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; 
}