一、什么是synchronizationcontext
SynchronizationContext(同步上下文),是一个抽象类,它表示线程上下文,用于协调异步方法(或代理线程)的回调。
使用同步上下文可以使得异步方法(或代理线程)的回调在正确的线程上下文中进行,这样可以避免由于线程上下文切换引发的问题,同时可以更好地掌控异步操作的生命周期。
其实,同步上下文是一种编程模型,它允许多个线程之间的协作,使得程序员可以更加轻松地编写异步代码。
二、异步任务的执行流程
异步任务指的是那些在独立的线程中执行的耗时操作。在使用同步上下文时,异步任务会通过同步上下文来将结果返回到原始的线程上下文中。整个执行流程如下:
1、启动异步任务
public async void Button_Click(object sender, EventArgs e)
{
Debug.WriteLine("UI thread id: " + Thread.CurrentThread.ManagedThreadId);
await DoSomethingAsync();
}
2、异步操作调用同步上下文
// 创造同步上下文
SynchronizationContext ctx = SynchronizationContext.Current;
Debug.WriteLine("context's thread id: " + Thread.CurrentThread.ManagedThreadId);
// 异步操作
var result = await Task.Run(() =>
{
Debug.WriteLine("task's thread id: " + Thread.CurrentThread.ManagedThreadId);
return ComplexComputation(ctx); // <-- 调用同步上下文
});
3、同步上下文切换到主线程
private void ComplexComputation(SynchronizationContext ctx)
{
var result = SomeLongOperation();
ctx.Post(state => HandleResult(result), null);
}
private void HandleResult(object result)
{
Debug.WriteLine("on UI thread id: " + Thread.CurrentThread.ManagedThreadId);
Debug.WriteLine("Result: " + result.ToString());
}
三、SynchronizationContext的类型
在.NET中,有三种常见的SynchronizationContext类型:
1、WindowsFormsSynchronizationContext
WindowsFormsSynchronizationContext主要用于Windows Forms应用程序。当异步操作完成时,它会将结果返回到主线程,使得我们可以更新UI。
// 创造同步上下文
SynchronizationContext ctx =
WindowsFormsSynchronizationContext.Current;
// 异步操作
var result = await Task.Run(() =>
{
return SomeLongOperation();
});
// 回调到主线程
ctx.Post(state =>
{
textBox1.Text = result.ToString();
}, null);
2、TaskScheduler
TaskScheduler是一个线程池,当异步任务完成时,它会使用回调线程池来处理异步回调。
// 创造同步上下文
var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
// 异步操作
Task.Run(() =>
{
return SomeLongOperation();
})
.ContinueWith(task =>
{
// 处理结果
textBox1.Text = task.Result.ToString();
}, CancellationToken.None, TaskContinuationOptions.None, scheduler);
3、AspNetSynchronizationContext
AspNetSynchronizationContext主要用于ASP.Net应用程序。当异步操作完成时,它会将结果返回到AspNet请求处理程序中,使得我们可以更新Web UI。
// 创造同步上下文
SynchronizationContext ctx = new AspNetSynchronizationContext();
// 异步操作
var result = await Task.Run(() =>
{
return SomeLongOperation();
});
// 回调
ctx.Post(state => {
Response.Write(result.ToString());
}, null);
四、与async/await的结合使用
同步上下文可以与async/await一起使用,这样可以使得异步代码更加可读、可维护。
private async void Button_Click(object sender, RoutedEventArgs e)
{
// 运行异步方法
var result = await LongOperationAsync();
// 更新UI
Label.Content = result.ToString();
}
private async Task LongOperationAsync()
{
// 访问网络
await Task.Delay(TimeSpan.FromSeconds(5));
// 返回结果
return 42;
}
总结
在编写异步代码时,同步上下文是一个非常重要的概念。它可以确保异步操作的回调在正确的线程上下文中执行,同时可以更加轻松地编写可读、可维护的异步代码。在.NET中,常见的同步上下文类型包括WindowsFormsSynchronizationContext、TaskScheduler、AspNetSynchronizationContext等。
原创文章,作者:FABQ,如若转载,请注明出处:https://www.506064.com/n/144131.html