线程isAlive后的事件

本文关键字:事件 isAlive 线程 | 更新日期: 2023-09-27 18:14:42

我有一个表单,标签文本为"Loading"。

label1.Text = "Loading...";

。加载我有一个新的线程,它正在做一些事情,让我们这样说。

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属性更改为"Finished"。但在哪里以及如何改变,我不知道。我正在学习线程。我是否必须创建一个线程来做这个不断检查线程"t"的isAlive属性?

线程isAlive后的事件

如果你的任务真的在另一个线程中做一些事情,并将结果发布到gui中,你应该看看BackgroundWorker类。

如果这对你来说是不可能的,你可以看看乔的线程文章。它应该能回答你所有关于线程的问题。

如果您需要后台工作人员的进一步帮助,只需在网上或在这里进行搜索。下面是我的一个答案,展示了如何使用后台worker。

你有多个解决方案。如果你真的想使用Thread类,你可以调用Join方法,但是这会阻塞UI线程,这不是一件好事。还可以在for循环之后调用窗体的Invoke方法,如下

void run()
{
    for (int i = 0; i < 100000000; i++)
    {
    }
    this.Invoke(new Action(() => this.label1.Text = "done"));
}

调用方法是必需的,因为您是在windows窗体中,并且调用方法将在UI线程上执行您的代码。

除了使用Thread类,你还可以看看Delegate。BeginInvoke和at System.Threading.Tasks。它们都更有效,因为它将线程池和提供回调来分离您的拆装代码。

不,一点也不。您需要向UI线程(处理表单的线程)发送消息。阅读本文获取一些信息:如何从c#中的另一个线程更新GUI ?

easy

void run()
{
   for(int i = 0; i < 1000000; i++)
   {
   }
   Invoke(new MethodInvoker(delegate()
                                         {
                                             label1.Text = "finished";
                                         }));
}

或者引发事件但是在这种简单的情况下这样做并不重要

看看。net 4附带的TPL任务并行库。这使您有机会轻松启动后台工作程序,并定义在第一个任务完成后启动的另一个任务。真正聪明的是,第二个任务(和其他任何任务一样)可以配置为在UI线程上运行,这样你就不必在任务操作中进行切换。

就像这里的小例子:

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

如果您愿意使用异步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;
}

可能最简单的事情是让run在完成时引发事件,并让表单为该事件附加处理程序

将对标签或表单的引用传递给线程,并使用Invokelabel1.Text="Completed"