学习C#异步编程
2020-12-29 22:28
标签:负载 lam 模型 sys 输出内容 其它 对象 安全 reading "杨老师视频教程" 视频地址 什么是线程Thread 例子: 视频地址 调用Join方法,就可以等待另一个线程结束。 例子: 输出内容: Current Thread:thread1 Current Thread:thread2 Current thread:thread2 Current thread:thread1 例子: 输出: Current Thread:thread1 Current Thread:thread2 Current thread:thread2 Current thread:thread1 Thread.Sleep()方法会暂停当前的线程,并等待一段时间。 注意: Sleep(0)或Yield有时在高级性能调试的生产代码中很有用。它也是一个很好的诊断工具,有助于发现线程安全问题: 如果在代码中的任何地方插入Thread.Yield()就破坏了程序,那么你的程序几乎肯定有bug。 视频地址 如果线程的执行由于某种原因导致暂停,那么就认为该线程被阻塞了。 被阻塞的线程会立即将其处理器的时间片生成给其它线程,从此就不再消耗处理器时间,直到满足其阻塞条件为止。 可以通过ThreadState这个属性来判断线程是否处于被阻塞的状态: ThreadState是一个flags enum,通过按位的形式,可以合并数据的选项。 Blocking vs Spinning IO-bound操作的工作方式有两种: 同步等待的I/O-bound操作将大部分时间花在阻塞线程上。 它们也可以周期性的在一个循环里进行“打转(自旋)” 在忙等待和阻塞方面有一些细微差别。 视频地址 视频地址 在C#3.0之前,没有lambda表达式。可以使用Thread的Start方法来传递参数。 Thread的重载构造函数可以接受下列两个委托之一作为参数: 视频地址 视频地址 提升线程优先级的时候需特别注意,因为它可能“饿死”其它线程。 如果想让某线程(Thread)的优先级比其它进程(Process)中的线程(Thread)高,那就必须提升进程(Process)的优先级。 使用System.Diagnostics下的Process类。 这可以很好地用于只做少量工作且需要较低延迟的非UI进程。 对于需要大量计算的应用程序(尤其是有UI的应用程序),提高进程优先级可能会使其它进程饿死,从而降低整个计算机的速度。 视频地址 视频地址 视频地址 视频地址 视频地址 Task.Run 默认情况下,CLR在线程池中运行Task,这非常适合短时间运行的Compute-Bound类工作。 针对长时间运行的任务或者阻塞操作,你可以不采用线程池。 如果同时运行多个long-running tasks(尤其是其中有处于阻塞状态的),那么性能将会受很大影响,这时有比TaskCreationOptions.LongRunning更好的办法: 视频地址 视频地址 学习C#异步编程 标签:负载 lam 模型 sys 输出内容 其它 对象 安全 reading 原文地址:https://www.cnblogs.com/zzr-stdio/p/13283056.htmlP1 线程(Thread):创建线程
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(WriteY); //开启一个新的线程 Thread
thread.Name = "Y Thread...";
thread.Start();
for (int i = 0; i
术语:线程被抢占
线程的一些属性
P2 Thread.Join()&Thread.Sleep()
Join and Sleep
class Program
{
static void Main(string[] args)
{
Thread t = new Thread(WriteY);
t.Start();
t.Join();//当前线程会等待t线程执行结束
Console.WriteLine("线程结束");
Console.Read();
}
private static void WriteY()
{
for(int i = 0; i
class Program
{
static Thread thread1, thread2;
static void Main(string[] args)
{
thread1 = new Thread(ThreadProc);
thread1.Name = nameof(thread1);
thread1.Start();
thread2 = new Thread(ThreadProc);
thread2.Name = nameof(thread2);
thread2.Start();
Console.Read();
}
private static void ThreadProc()
{
Console.WriteLine($"\nCurrent Thread:{Thread.CurrentThread.Name}");
if (Thread.CurrentThread.Name == nameof(thread1) &&
thread2.ThreadState != ThreadState.Unstarted)
thread2.Join();
Thread.Sleep(4000);
Console.WriteLine($"\nCurrent thread:{Thread.CurrentThread.Name}");
Console.WriteLine($"Thread1:{thread1.ThreadState}");
Console.WriteLine($"Thread2:{thread2.ThreadState}");
}
}
Thread1:WaitSleepJoin
Thread2:Running
Thread1:Running
Thread2:Stopped添加超时
class Program
{
static Thread thread1, thread2;
static void Main(string[] args)
{
thread1 = new Thread(ThreadProc);
thread1.Name = nameof(thread1);
thread1.Start();
thread2 = new Thread(ThreadProc);
thread2.Name = nameof(thread2);
thread2.Start();
Console.Read();
}
private static void ThreadProc()
{
Console.WriteLine($"\nCurrent Thread:{Thread.CurrentThread.Name}");
if (Thread.CurrentThread.Name == nameof(thread1) &&
thread2.ThreadState != ThreadState.Unstarted)
if (thread2.Join(2000))
Console.WriteLine("线程2结束");
else
Console.WriteLine("线程2超时了");
Thread.Sleep(4000);
Console.WriteLine($"\nCurrent thread:{Thread.CurrentThread.Name}");
Console.WriteLine($"Thread1:{thread1.ThreadState}");
Console.WriteLine($"Thread2:{thread2.ThreadState}");
}
}
线程2超时了
Thread1:WaitSleepJoin
Thread2:Running
Thread1:Running
Thread2:Stopped
P3 阻塞Blocking
阻塞
bool blocked = (thread.ThreadState & ThreadState.WaitSleepJoin) != 0;
ThreadState
//
// 摘要:
// 指定 System.Threading.Thread 的执行状态。
[ComVisible(true)]
[Flags]
public enum ThreadState
{
//
// 摘要:
// 线程已启动且尚未停止。
Running = 0,
//
// 摘要:
// 正在请求线程停止。 这仅用于内部。
StopRequested = 1,
//
// 摘要:
// 正在请求线程挂起。
SuspendRequested = 2,
//
// 摘要:
// 线程正作为后台线程执行(相对于前台线程而言)。 此状态可以通过设置 System.Threading.Thread.IsBackground 属性来控制。
Background = 4,
//
// 摘要:
// 尚未对线程调用 System.Threading.Thread.Start 方法。
Unstarted = 8,
//
// 摘要:
// 线程已停止。
Stopped = 16,
//
// 摘要:
// 线程已被阻止。 这可能是调用 System.Threading.Thread.Sleep(System.Int32) 或 System.Threading.Thread.Join、请求锁定(例如通过调用
// System.Threading.Monitor.Enter(System.Object) 或 System.Threading.Monitor.Wait(System.Object,System.Int32,System.Boolean))或在线程同步对象上(例如
// System.Threading.ManualResetEvent)等待的结果。
WaitSleepJoin = 32,
//
// 摘要:
// 线程已挂起。
Suspended = 64,
//
// 摘要:
// 已对线程调用了 System.Threading.Thread.Abort(System.Object) 方法,但线程尚未收到试图终止它的挂起的 System.Threading.ThreadAbortException。
AbortRequested = 128,
//
// 摘要:
// 线程状态包括 System.Threading.ThreadState.AbortRequested 并且该线程现在已死,但其状态尚未更改为 System.Threading.ThreadState.Stopped。
Aborted = 256
}
接触阻塞
上下文切换
I/O-bound vs Compute-bound(或CPU-Bound)
阻塞 vs 忙等待(自旋)
while(DateTime.Now
P4 什么是线程安全
本地 vs 共享的状态
Local 本地独立
Shared共享
线程安全 Thread Safety
锁定与线程安全简介
P5 向线程传递数据&异常处理
向线程传递数据
向线程传递数据在C#3.0之前
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
Lambda表达式与被捕获的变量
异常处理
P6 前台线程 vs 后台线程
Foreground vs Background Threads
P7 线程优先级
线程优先级
提升线程优先级
using (Process p = Process.GetCurrentProcess())
{
p.PriorityClass = ProcessPriorityClass.High;
}
P8 信号介绍
信号 Signaling
P9 富客户端应用处理耗时操作的一种办法
富客户端应用程序的线程
P10 Synchronization Context
Synchronization Contexts 同步上下文
P11 线程池
线程池 Thread Pool
使用线程池需要注意的几点
进入线程池
谁使用了线程池
线程池中的整洁
CLR的策略
P12 开始一个Task
Thread的问题
Task Class
开始一个Task
Wait 等待
Long-running tasks 长时间运行的任务
Task task = Task.Factory.StartNew(() => { }, TaskCreationOptions.LongRunning);
P13 Task的返回值
Task的返回值
P14 Task的异常
Task异常
异常与“自治”的Task
未观察到的异常