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

C# 线程完成后如何调用函数?,c#,multithreading,C#,Multithreading,我尝试在线程完成后调用函数,但无法。 我只能在函数调用方代码之前使用while(threadName.isAlive)方法,但这不好,因为当我使用此代码时程序停止。你知道吗 public partial class Form1 : Form { Thread myThread; string myString = string.Empty; public Form1() { InitializeComponent(); } pr

我尝试在线程完成后调用函数,但无法。 我只能在函数调用方代码之前使用
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);
        }
    }
}
公共部分类表单1:表单
{
线程读取;
string myString=string.Empty;
公共表格1()
{
初始化组件();
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
myThread=新线程(写入);
myThread.Start();
while(myThread.IsAlive);
textBox1.Text=myString;
}
公共空写()
{
对于(int i=0;i<10;i++){
myString+=“aaa”+i+“\r\n”;
睡眠(1000);
}
}
}
如果必须附加到
线程而不是
任务
,则只需启动任务等待线程退出,然后运行一些附加代码,如下所示:

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");
        }
    }
}
然而,实现这一点的现代方法是使用
任务
等待
异步

例如:

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;
}

线程
切换到
任务
,让.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; 
}
公共异步任务写入(){
string myString=string.Empty;
对于(int i=0;i<10;i++){
myString+=“aaa”+i+“\r\n”;
等待任务。延迟(1000);
}
返回myString;
}
私有异步无效按钮1\u单击(对象发送方,事件参数e){
字符串结果=等待写入();
//继续分配(请注意,等待)
textBox1.Text=结果;
}

请添加您的代码似乎您想要的是
任务
,而不是
线程
我的任务。继续(…)
可能重复的
线程
主要关注机制。正如其他人所说,您可以创建一个更现代的
任务
,或者您可以让自己完全跟上时代,接受
async
/
wait
。这样做,您甚至可以在适当的时间直接与UI交互(如果
线程。睡眠
变成
任务。延迟
并代表I/O工作,而不是CPU工作)。首先要学习的是,您不应该(几乎)使用线程。使用Tasks和async/await。我只想学习。我使用此代码,我想使用textbox而不是console.writeline。但是它给了我这个错误->System.Windows.Forms.dll中发生了“System.InvalidOperationException”类型的异常,但没有在用户代码中处理其他信息:跨线程操作无效:控件“textBox1”是从创建它的线程以外的线程访问的。@amirmehr如果您看到我的第二个示例,它向您展示了如何做到这一点。但是,请注意,您需要.NET4.5或更高版本(我认为)才能这样做。