线程完成后如何调用函数?

时间:2018-07-20 08:38:49

标签: c# multithreading

我尝试在线程完成后调用一个函数,但不能。 我只能在函数调用程序代码之前使用while(threadName.isAlive)方法,但是不好,因为当我使用此代码时程序会停止。你有什么主意吗?

public partial class Form1 : Form
{
    Thread myThread;
    string myString = string.Empty;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        myThread = new Thread(write);
        myThread.Start();
        while (myThread.IsAlive) ;
        textBox1.Text = myString; 
    }

    public void write()
    {
        for (int i = 0; i < 10; i++) {

            myString += "aaa " + i + "\r\n";
            Thread.Sleep(1000);
        }
    }
}

2 个答案:

答案 0 :(得分:3)

Task切换到Thread,然后让.Net为您进行(低级)工作:

public async Task<string> write() {
  string myString = string.Empty;

  for (int i = 0; i < 10; i++) {
    myString += "aaa " + i + "\r\n";

    await Task.Delay(1000);
  }

  return myString;
}

private async void button1_Click(object sender, EventArgs e) {
  string result = await write();    

  // continue with (please, notice await) with assigning
  textBox1.Text = result; 
}

答案 1 :(得分:1)

如果必须附加到Thread而不是Task,则只需启动任务以等待线程退出,然后运行一些其他代码,像这样:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace Demo
{
    static class Program
    {
        static void Main()
        {
            Thread thread = new Thread(work);
            thread.Start();

            Task.Run(() =>
            {
                thread.Join();
                Console.WriteLine("Run after thread finished");
            });

            Console.ReadLine();
        }

        static void work()
        {
            Console.WriteLine("Starting work");
            Thread.Sleep(1000);
            Console.WriteLine("Finished work");
        }
    }
}

但是,解决此问题的现代方法是使用Taskawaitasync

例如:

async void button1_Click(object sender, EventArgs e)
{
    textBox1.Text = "Awaiting task";
    await writeAsync();
    textBox1.Text = "Task finished";
}

Task writeAsync()
{
    return Task.Run(() => write());
}

void write()
{
    Thread.Sleep(10000);
}

如果尝试第二种方法,则会看到UI保持响应,而文本框显示“正在等待任务”。

还要注意,通常您希望在等待任务时阻止用户再次按下按钮,以避免运行多个任务。最简单的方法是在任务处于活动状态时禁用按钮,如下所示:

async void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;

    textBox1.Text = "Awaiting task";
    await writeAsync();
    textBox1.Text = "Task finished";

    button1.Enabled = true;
}