标签:卡顿 事件 cto 处理器 多线程 for future 能力 没有
现在我们先说明几个概念:
Task
和 Task<TResult>
类型实现未来模式,在老式异步编程 API 中,采用回调或事件(event)async
和 await
解决的问题async
方法在开始时以同步方式执行。在 async
方法内部,运行到await
关键字会执行一个异步等待
async
方法,并返回,留下一个未完成的 task
。await
住的操作完成,async
方法就恢复运行(不一定是原来的线程,具体看同步上下文的配置)。await
语句等待一个任务完成,这时会捕捉同步上下文。
SynchronizationContext
不为空,这个上下文就是当前 SynchronizationContext
。SynchronizationContext
为空,则这个上下文为当前 TaskScheduler。注意: 最好的做法是,在核心库代码中一直使用
ConfigureAwait
。在外围的用户界面代码中,只在需要时才恢复上下文。
Task.Run
await
关键字,将任务交给线程池完成,解决读取时窗体卡顿情况TaskFactory.StartNew
TaskCompletionSource<T>
。
TaskCompletionSource<T>
。await
抛出的异常,我们更想要try
{
await Task.Run(() => throw new NotSupportedException());
}
catch (Exception ex)
{
//print: NotSupportedException
Console.WriteLine(ex.GetType().Name);
}
Wait()
方法,异常类型被包装try
{
Task task = Task.Run(() => throw new NotSupportedException());
task.Wait();
}
catch (Exception ex)
{
//print: AggregateException
Console.WriteLine(ex.GetType().Name);
}
反面教材: 之前在工作中出现一起事故,实施好的项目,3个月后每天凌晨出现大量设备掉线的情况。
- 由于数据超时时间时3个月,而且发现出现问题的日志和数据清理发生时间有关联关系
- 排查代码发现文件清理器,清理数据使用的Parallel类,并行删除文件,而且没有对并发数限制
- 文件清理器运行时,导致服务器性能急剧下降,造成处理设备消息延迟,心跳超时导致掉线
- 重构了文件清理器代码,解决了这个问题
不保证顺序执行。
//ForEach
int[] arr = new int[] { 1, 2, 3, 4 };
Parallel.ForEach(arr, item => Console.Write(item));
System.Console.WriteLine();
//PLINQ
var sum = arr.AsParallel().Select(item => item * 2).Sum();
System.Console.WriteLine($"sum:{sum}.");
//Invoke
int num = 10;
Parallel.Invoke(
() => num += 2,
() => num -= 2,
() => num -= num,
() => num += 2
);
System.Console.WriteLine($"num:{num}.");
/*
print:
1243
sum:20.
num:0.
*/
系统会把这些异常封装在 AggregateException 类里,在程序中抛给代码。 这一特点对所有方法都是一样的,包括 Parallel.ForEach、Paralle.lInvoke、Task.Wait 等。 AggregateException 类型有几个实用的 Flatten 和 Handle 方法,用来简化错误处理的代码:
try
{
Parallel.Invoke(() => { throw new Exception(); },
() => { throw new Exception(); });
}
catch (AggregateException ex)
{
ex.Handle(exception =>
{
Console.WriteLine(exception);
return true; //“已经处理”
});
}
在编写任务并行程序时,要格外留意下闭包(closure)捕获的变量。 记住闭包捕获的是引用(不是值),因此可以在结束时以不明显地方式地分享这些变量。
如果事件中带有参数,那么最好 采用响应式编程,而不是常规的事件处理程序。
//System.Runtime.dll namespace:System 中定义了这些接口
interface IObserver<in T>
{
void OnNext(T item);
void OnCompleted();
void OnError(Exception error);
}
interface IObservable<out T>
{
IDisposable Subscribe(IObserver<T> observer);
}
Rx(Rx-Main)中定义了响应式编程的封装,后面会有介绍。
标签:卡顿 事件 cto 处理器 多线程 for future 能力 没有
原文地址:https://www.cnblogs.com/BigBrotherStone/p/12237571.html