C# 多线程 05-使用 C#6.0 06-避免使用捕获的同步上下文
避免使用捕获的同步上下文
csharp
/// <summary>
/// 避免使用捕获的同步上下文
/// </summary>
/// <param name="args"></param>
[STAThread]
static void Main(string[] args)
{
var app = new Application();
var win = new Window();
var panel = new StackPanel();
var button = new Button();
_label = new Label();
_label.FontSize = 32;
_label.Height = 200;
button.Height = 100;
button.FontSize = 32;
button.Content = new TextBlock { Text = "开始异步操作" };
button.Click += Click;
panel.Children.Add(_label);
panel.Children.Add(button);
win.Content = panel;
app.Run(win);
Console.ReadLine();
}
private static Label _label;
static async void Click(object sender, EventArgs e)
{
_label.Content = new TextBlock { Text = "计算中......" };
TimeSpan resultWithContent = await Test();
TimeSpan resultNoContent = await TestNoContent();
//TimeSpan resultNoContent = await TestNoContent().ConfigureAwait(false);
var sb = new StringBuilder();
sb.AppendLine($"With the content: {resultWithContent}");
sb.AppendLine($"Without the content: {resultNoContent}");
sb.AppendLine($"Ratio: {resultWithContent.TotalMilliseconds / resultNoContent.TotalMilliseconds:0.00}");
_label.Content = new TextBlock { Text = sb.ToString() };
}
static async Task<TimeSpan> Test()
{
const int iterationsNumber = 100000;
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < iterationsNumber; i++)
{
var t = Task.Run(() => { });
await t;
}
sw.Stop();
return sw.Elapsed;
}
static async Task<TimeSpan> TestNoContent()
{
const int interationsNumber = 100000;
var sw = new Stopwatch();
sw.Start();
for (int i = 0; i < interationsNumber; i++)
{
var t = Task.Run(() => { });
// 将 continueOnCapturedContext 指定为 false,不使用捕获的同步上下文运行后续操作代码
await t.ConfigureAwait(continueOnCapturedContext: false);
}
sw.Stop();
return sw.Elapsed;
}
运行结果
txt
With the content: 00:00:04.5821377
Without the content: 00:00:02.4224249
Ratio: 1.89
如果在运行时不停的改变窗体大小,运行结果的比率会显著的变大:
txt
With the content: 00:00:16.0775755
Without the content: 00:00:03.2937352
Ratio: 4.88