110,565
社区成员
发帖
与我相关
我的任务
分享
private void button1_Click(object sender, EventArgs e)
{
Console.WriteLine($"当前主线程的ID是{Thread.CurrentThread.ManagedThreadId}");
for (int i = 0; i < 100; i++)
{
Console.WriteLine($"当前{i}的ID是{Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(100);
Task.Run(() =>
{
textBox1Set(i);
});
}
Console.WriteLine($"结束了");
}
public void textBox1Set(int I)//供当前及后续类写日志用
{
Console.WriteLine($"当前{I}的textBox1SetID是{Thread.CurrentThread.ManagedThreadId}");
textBox1.Invoke((EventHandler)delegate
{
textBox1.Text = I.ToString();
Console.WriteLine($"当前{I}的textBox1SetID的BeginInvoke是{Thread.CurrentThread.ManagedThreadId}");
});
}
private async void button1_Click(object sender, EventArgs e)
{
Console.WriteLine($"当前主线程的ID是{Thread.CurrentThread.ManagedThreadId}");
for (int i = 0; i < 100; i++)
{
Console.WriteLine($"当前{i}的ID是{Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(100);
await Task.Run(() =>
{
textBox1Set(i);
});
}
Console.WriteLine($"结束了");
}
public void textBox1Set(int I)//供当前及后续类写日志用
{
Console.WriteLine($"当前{I}的textBox1SetID是{Thread.CurrentThread.ManagedThreadId}");
textBox1.Invoke((EventHandler)delegate
{
textBox1.Text = I.ToString();
Console.WriteLine($"当前{I}的textBox1SetID的BeginInvoke是{Thread.CurrentThread.ManagedThreadId}");
});
}
private async void button1_Click(object sender, EventArgs e)
{
//当前还是同步执行,并没有开始异步 所以线程为UI线程(主线程:线程1)
Console.WriteLine($"当前主线程的ID是{Thread.CurrentThread.ManagedThreadId}");
for (int i = 0; i < 100; i++)
{
//第一次循环(i=0)时,没有开始任何异步等待(await)所以依然是主线程
Console.WriteLine($"当前{i}的ID是{Thread.CurrentThread.ManagedThreadId}");
//第一次循环(i=0)UI线程会阻塞100ms(程序窗口会失去响应100ms),你可以时间改长一点观察以下。
Thread.Sleep(100);
//此处才开始异步,await机制可以参考两位大神说的,大致就是.net从线程池选择合适的线程执行
//第二次循环(i=1)时,.net重新执行await。
//也就是说从第一次循环的await开始至此方法(button1_Click)结束都是异步 。每次执行至await .net会重新从线程池中选择合适线程。
await Task.Run(() =>
{
textBox1Set(i);
});
}
Console.WriteLine($"结束了");
}
public void textBox1Set(int I)//供当前及后续类写日志用
{
Console.WriteLine($"当前{I}的textBox1SetID是{Thread.CurrentThread.ManagedThreadId}");
// textBox1.Invoke意思就是将代码委托至textBox1创建的线程执行,所以一定是UI线程
//如果使用的时.net framework Winfrom控件的Invoke(Control.Invoke)与委托的Invoke(delegate.Invoke)机制是不同的,
//相关资料有很多,自己搜。
textBox1.Invoke((EventHandler)delegate
{
textBox1.Text = I.ToString();
Console.WriteLine($"当前{I}的textBox1SetID的BeginInvoke是{Thread.CurrentThread.ManagedThreadId}");
});
}
private async void button1_Click(object sender, EventArgs e)
{
await semaphore.WaitAsync();
await WaitButton2Click();
await semaphore.WaitAsync();
MessageBox.Show("我等到了button2的点击");
semaphore.Release();
}
System.Threading.SemaphoreSlim semaphore = new SemaphoreSlim(1);
async Task WaitButton2Click()
{
EventHandler action = null;
action = (object sender1, EventArgs e1) =>
{
semaphore.Release();
button2.Click -= action;
};
button2.Click += action;
}
这里个是一个很简单的演示,点击button,然后用一个异步信号量去暂时释放执行权,等待这个信号量完成,一进行下部的弹框。这例子其实就是告诉那些人不是开启线程,而是等待某个状态完成
ps:那些博大神另一个引以为傲的玩意,所谓IOCP其实就是这种操作。当然那些伙计同样是一贯路子选择性忘记的单向输出。
IOCP其实与C#无关,也和线程无关,他是windows在南桥芯片管理下的IO操作,由windows 网卡驱动,在中断驱动下,直接由DMA操作进行内存写入,写入完成,发起一个IO完成信号。至于他进程也好,线程也罢,其实是就入上面那个代码一样,只是做了一个信号量等待,等待网卡驱动通知你内存写入完成,请继续下面一步
await socket.receiverAsync using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"开始, thread id = {Thread.CurrentThread.ManagedThreadId}");
test();
Console.WriteLine($"主线程test完毕, thread id = {Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine("按任意键结束........");
Console.ReadKey();
}
private static async void test()
{
Console.WriteLine($"test, thread id = {Thread.CurrentThread.ManagedThreadId}");
var task = Task.Run(async () =>
{
int cnt = 0;
while (cnt++ < 20)
{
await Task.Delay(1000);
Console.WriteLine($"while, thread id = {Thread.CurrentThread.ManagedThreadId}");
}
});
await Task.WhenAll(task); //await语句并未阻塞4的执行
Console.WriteLine($"while 完成, thread id = {Thread.CurrentThread.ManagedThreadId}");
}
}
}
在我这里它输出开始, thread id = 1
test, thread id = 1
主线程test完毕, thread id = 1
按任意键结束........
while, thread id = 4
while, thread id = 4
while, thread id = 4
while, thread id = 7
while, thread id = 4
while, thread id = 4
while, thread id = 4
while, thread id = 4
while, thread id = 4
while, thread id = 6
while, thread id = 6
while, thread id = 4
while, thread id = 4
while, thread id = 6
while, thread id = 6
while, thread id = 6
while, thread id = 7
while, thread id = 7
while, thread id = 7
while, thread id = 4
while 完成, thread id = 4
可以看到,await 不阻塞线程,同时也能灵活复用和重新分配线程。