技术归档文章随笔一句话导航搜索关于

.NET 异步模型

日期: 2025-04-20 分组: .NET 标签: .NET 3分钟 478字
1
using System.Diagnostics;
2
using System.Globalization;
3
using System.Runtime.CompilerServices;
4
using System.Security.Cryptography;

AsyncLocal

1
static System.Threading.AsyncLocal<int> myValue = new ();
2
3
await AsyncLocalTestAsync();
4
5
static async Task AsyncLocalTestAsync()
6
{
7
myValue.Value = 5;
8
9
Console.WriteLine($"In Main, myValue = {myValue.Value}"); // 1
10
11
await MyMethodAsync();
12
13
Console.WriteLine($"Back in Main, myValue = {myValue.Value}"); // 4
14
}
15
9 collapsed lines
16
static async Task MyMethodAsync()
17
{
18
myValue.Value = 10;
19
Console.WriteLine($"In MyMethod, myValue = {myValue.Value}"); // 2
20
21
await Task.Delay(500);
22
23
Console.WriteLine($"In MyMethod, after delay, myValue = {myValue.Value}"); // 3
24
}

TaskFactoryStartNew

1
static void TaskFactoryStartNewTest()
2
{
3
Task.Run(() => { }, new CancellationToken());
4
5
Task.Factory.StartNew(() => {
6
7
}, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default);
8
}
9
## TaskCompletionSource
10
static Task<int> TaskCompletionSourceTestAsync()
11
{
12
var tcs = new TaskCompletionSource<int>();
13
14
new Thread(() =>
15
{
8 collapsed lines
16
Thread.Sleep(500);
17
tcs.SetResult(5);
18
}).Start();
19
20
return tcs.Task;
21
}
22
23
Console.WriteLine(await TaskCompletionSourceTestAsync());

TaskContinuation

1
static async Task<int> TaskContinuationTestAsync(bool isException,TaskContinuationOptions opt)
2
{
3
return await Task.Run(() =>
4
{
5
if(isException)
6
throw new ArgumentException();
7
8
return 10;
9
}).ContinueWith((t) =>
10
{
11
var ex = t.Exception;
12
13
if (ex != null)
14
{
15
Console.WriteLine("出现了异常");
10 collapsed lines
16
return default;
17
}
18
19
return t.Result;
20
}, opt);
21
}
22
23
Console.WriteLine(await TaskContinuationTestAsync(true, TaskContinuationOptions.OnlyOnFaulted));
24
Console.WriteLine(await TaskContinuationTestAsync(true, TaskContinuationOptions.AttachedToParent));
25
Console.WriteLine(await TaskContinuationTestAsync(false, TaskContinuationOptions.None));

TaskAwaiter

1
await MyAwaitable.Test();
2
3
public class MyAwaitable
4
{
5
//实现一个 GetAwaiter 方法,并返回一个自定义的等待器对象。
6
public MyAwaiter GetAwaiter()
7
{
8
return new MyAwaiter(this);
9
}
10
11
//继承System.Runtime.CompilerServices.INotifyCompletion
12
public class MyAwaiter : INotifyCompletion
13
{
14
private readonly MyAwaitable _myAwaitable;
15
39 collapsed lines
16
public MyAwaiter(MyAwaitable myAwaitable)
17
{
18
_myAwaitable = myAwaitable;
19
}
20
21
//private bool _unCompleted = true;
22
//public bool IsCompleted => (_unCompleted = !_unCompleted);
23
24
//在等待器类型中定义一个布尔值字段来表示是否已经完成
25
public bool IsCompleted => false;
26
27
public void OnCompleted(Action continuation)
28
{
29
Console.WriteLine("Continuation requested");
30
31
continuation();
32
}
33
34
//在等待器对象中实现 GetResult 方法,该方法应在异步操作完成时返回结果。
35
public void GetResult()
36
{
37
Console.WriteLine("GetResult called");
38
}
39
}
40
41
42
/// <summary>
43
/// 测试代码
44
/// </summary>
45
/// <returns></returns>
46
public static async Task Test()
47
{
48
var awaitable = new MyAwaitable();
49
50
await awaitable;
51
52
Console.WriteLine("Hello Word!");
53
}
54
}

Task.WhenAll

1
await TaskWhenAllTestAsync();
2
3
public static async Task TaskWhenAllTestAsync()
4
{
5
Stopwatch stopwatch = Stopwatch.StartNew();
6
7
stopwatch.Start();
8
9
await Task.Delay(1000);
10
11
await Task.Delay(2000);
12
13
stopwatch.Stop();
14
15
Console.WriteLine(stopwatch.Elapsed);
26 collapsed lines
16
17
stopwatch.Restart();
18
19
await Task.WhenAll(Task.Delay(1000), Task.Delay(2000));
20
21
stopwatch.Stop();
22
23
Console.WriteLine(stopwatch.Elapsed);
24
25
Task<int> t1 = Task.FromResult<int>(1), t2 = Task.FromResult(2);
26
27
28
var (r1, r2) = TaskHelper.WhenAll(t1, t2);
29
30
Console.WriteLine(r1 + r2);
31
}
32
33
public static class TaskHelper
34
{
35
public static (T1 t1, T2 t2) WhenAll<T1, T2>(Task<T1> t1, Task<T2> t2)
36
{
37
Task.WaitAll(t1, t2);
38
39
return (t1.Result, t2.Result);
40
}
41
}

Task Lock

1
public static async Task LockTestAsync()
2
{
3
var lockObj = new object();
4
lock (lockObj)
5
{
6
// Error: (6,8): error CS1996: 无法在 lock 语句体中等待
7
// await Task.Delay(1000);
8
}
9
10
var isEnter = Monitor.TryEnter(lockObj);
11
if (!isEnter)
12
{
13
return;
14
}
15
12 collapsed lines
16
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
17
18
await Task.Delay(100);
19
//await Task.FromResult(10);
20
21
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
22
23
if (isEnter)
24
{
25
Monitor.Exit(lockObj);
26
}
27
}

尽量避免生成状态机

1
public static async Task StateMachineAsync()
2
{
3
await Task.Delay(1000);
4
}
5
6
public static Task NoStateMachineAsync()
7
{
8
return Task.Delay(1000);
9
}
人应当是有理想的.
文章目录