diff --git a/HW-Async&Thread-1/Program.cs b/HW-Async&Thread-1/Program.cs
index 6965f01..9a63bd7 100644
--- a/HW-Async&Thread-1/Program.cs
+++ b/HW-Async&Thread-1/Program.cs
@@ -1,125 +1,149 @@
-namespace HW_Async_Thread;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
-public class Program
+namespace HW_Async_Thread
{
- public static void Main()
+ public class Program
{
- // 测试用例: (a + b) + (c + d)
- // 可以自行修改测试用例
- ValueExpr a = new(1);
- ValueExpr b = new(2);
- ValueExpr c = new(3);
- ValueExpr d = new(4);
- AddExpr add1 = new(a, b);
- AddExpr add2 = new(c, d);
- AddExpr add3 = new(add1, add2);
- Console.WriteLine(add3.Val);
- a.NewVal = 5;
- Console.WriteLine(add3.Val);
- }
-}
+ public static async Task Main()
+ {
+ // 测试用例: (a + b) + (c + d)
+ ValueExpr a = new ValueExpr(1);
+ ValueExpr b = new ValueExpr(2);
+ ValueExpr c = new ValueExpr(3);
+ ValueExpr d = new ValueExpr(4);
+ AddExpr add1 = new AddExpr(a, b);
+ AddExpr add2 = new AddExpr(c, d);
+ AddExpr add3 = new AddExpr(add1, add2);
-///
-/// 表达式结点抽象类,用于构造表达式树
-///
-public abstract class Expr
-{
- ///
- /// 父结点
- ///
- protected Expr? parent = null;
-
- ///
- /// 表达式的值,只允许返回一个现成的值,可以加锁
- /// 拓展思考:是否所有时候读取到的值都是其正确的值?如何避免?
- ///
- public abstract int Val { get; }
-
- ///
- /// 异步方法,它的作用是启动一个任务,推动结点自身及其父结点更新值
- /// 可以根据自身需求适当修改方法签名
- ///
- public abstract Task Update();
-
- ///
- /// 注册父结点
- /// 思考:当父结点被注册后,父结点的值是否需要更新?
- ///
- /// 待注册的父结点
- public abstract void Register(Expr parent);
-}
-///
-/// 数据结点
-///
-/// 初始值
-public class ValueExpr(int initVal) : Expr
-{
- int val = initVal;
- public override int Val
- {
- get
- {
- // TODO 1:读取操作
- return val;
+ Console.WriteLine(await add3.Val);
+
+ a.NewVal = 5;
+ await add3.Update();
+
+
+ Console.WriteLine(await add3.Val);
}
}
- ///
- /// 修改数据
- /// 思考:修改数据后,父结点是否也需要更新?
- ///
- public int NewVal
+ public abstract class Expr
{
- set
+ protected readonly List parents = new List();
+ private readonly SemaphoreSlim semaphore = new SemaphoreSlim(1, 1);
+ protected bool isDirty = true;
+
+ public abstract Task GetValAsync();
+
+ public Task Val
{
- // TODO 2:修改操作
+ get
+ {
+ return GetValAsync();
+ }
}
- }
- public override async Task Update()
- {
- // TODO 3:更新操作
- }
+ public abstract Task Update();
- public override void Register(Expr parent)
- {
- // TODO 4:注册操作
- }
-}
+ public abstract void Register(Expr parent);
-///
-/// 加法表达式结点
-/// 可以根据自己的想法创造更多种类的结点
-///
-public class AddExpr : Expr
-{
- int val = 0;
- public override int Val
- {
- get
+ protected void NotifyParents()
{
- // TODO 5:读取操作
- return val;
+ foreach (var parent in parents)
+ {
+ _ = parent.Update();
+ }
}
- }
- public Expr ExprA, ExprB;
- public AddExpr(Expr A, Expr B)
- {
- ExprA = A;
- ExprB = B;
- A.Register(this);
- B.Register(this);
+ protected async Task WaitForUpdate()
+ {
+ await semaphore.WaitAsync();
+ try
+ {
+ await Update();
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
}
- public override async Task Update()
+ public class ValueExpr : Expr
{
- // TODO 6:更新操作
+ private int val;
+
+ public ValueExpr(int initVal)
+ {
+ val = initVal;
+ }
+
+ public override Task GetValAsync()
+ {
+ return Task.FromResult(val);
+ }
+
+ public int NewVal
+ {
+ set
+ {
+ if (val != value)
+ {
+ val = value;
+ NotifyParents();
+ }
+ }
+ }
+
+ public override Task Update()
+ {
+ return Task.CompletedTask;
+ }
+
+ public override void Register(Expr parent)
+ {
+ parents.Add(parent);
+ }
}
- public override void Register(Expr parent)
+ public class AddExpr : Expr
{
- // TODO 7:注册操作
+ private int val;
+ private readonly Expr exprA;
+ private readonly Expr exprB;
+
+ public AddExpr(Expr A, Expr B)
+ {
+ exprA = A;
+ exprB = B;
+ A.Register(this);
+ B.Register(this);
+ }
+
+ public override async Task GetValAsync()
+ {
+ if (isDirty)
+ {
+ await WaitForUpdate();
+ }
+ return val;
+ }
+
+ public override async Task Update()
+ {
+ await Task.WhenAll(exprA.GetValAsync(), exprB.GetValAsync());
+ val = await exprA.GetValAsync() + await exprB.GetValAsync();
+ isDirty = false;
+ NotifyParents();
+ }
+
+ public override void Register(Expr parent)
+ {
+ parents.Add(parent);
+ }
}
}
+
+