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或更高版本(我认为)才能这样做。