一、什麼是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/zh-hant/n/144131.html