C#中同触发源类间数据传递与执行顺序保障问题
解决方案
当然可以实现,下面是几种实用的思路:
1. 显式依赖注入 + 手动控制执行顺序
把SomeClass1的实例注入到SomeClass2中,在触发源里严格控制执行顺序,或者让SomeClass2内部先调用SomeClass1的逻辑再执行自身计算。
修改后的代码示例:
// 调整SomeClass2,通过构造函数注入SomeClass1依赖 public class SomeClass2 : SomeBaseClass { private readonly SomeClass1 _someClass1; public SomeClass2(SomeClass1 someClass1) { _someClass1 = someClass1; } public override ISomeTable Calculate(string s) { // 先执行SomeClass1的逻辑并获取结果 var class1Result = _someClass1.Calculate(s); // 从结果中提取需要共享的字典数据 var sharedDict = ExtractSharedDictionary(class1Result); // 基于共享数据执行SomeClass2的专属逻辑 var someTable2 = new SomeTableImpl(); // ... 这里写入使用sharedDict的计算逻辑 return someTable2; } // 辅助方法:从ISomeTable中提取共享字典 private Dictionary<string, object> ExtractSharedDictionary(ISomeTable table) { // 示例:假设ISomeTable有获取字典的方法 return table.GetCalculatedDictionary(); } } // 触发源处的执行逻辑 var class1 = new SomeClass1(); var class2 = new SomeClass2(class1); // 确保先完成SomeClass1的计算,再执行SomeClass2 var result1 = class1.Calculate("input"); var result2 = class2.Calculate("input");
2. 引入共享上下文对象
创建一个专门的上下文类存储共享数据,触发源控制执行顺序:先让SomeClass1把结果写入上下文,再让SomeClass2从上下文读取数据后执行计算。
代码示例:
// 定义共享上下文 public class CalcContext { public Dictionary<string, object> SharedData { get; set; } = new(); } // 修改SomeClass1,写入数据到上下文 public class SomeClass1 : SomeBaseClass { private readonly CalcContext _context; public SomeClass1(CalcContext context) { _context = context; } public override ISomeTable Calculate(string s) { var someTable1 = new SomeTableImpl(); // 执行逻辑后,将共享字典写入上下文 _context.SharedData = GenerateSharedData(someTable1); return someTable1; } private Dictionary<string, object> GenerateSharedData(ISomeTable table) { // 生成需要共享的字典数据 return new() { { "key1", "value1" }, { "key2", 123 } }; } } // 修改SomeClass2,从上下文读取数据 public class SomeClass2 : SomeBaseClass { private readonly CalcContext _context; public SomeClass2(CalcContext context) { _context = context; } public override ISomeTable Calculate(string s) { // 检查上下文是否有数据,确保SomeClass1已执行 if (_context.SharedData == null || _context.SharedData.Count == 0) { throw new InvalidOperationException("请先执行SomeClass1的计算逻辑"); } var sharedData = _context.SharedData; var someTable2 = new SomeTableImpl(); // ... 这里写入使用sharedData的计算逻辑 return someTable2; } } // 触发源处的执行逻辑 var context = new CalcContext(); var class1 = new SomeClass1(context); var class2 = new SomeClass2(context); // 严格按顺序执行 class1.Calculate("input"); var result2 = class2.Calculate("input");
3. 事件驱动解耦(适合复杂场景)
让SomeClass1执行完成后触发事件,SomeClass2订阅该事件,在回调中接收共享数据并执行自身逻辑,实现解耦的同时保证顺序。
代码示例:
// 定义事件参数,携带共享数据和输入参数 public class CalcCompletedArgs : EventArgs { public Dictionary<string, object> SharedData { get; set; } public string Input { get; set; } } public class SomeClass1 : SomeBaseClass { // 定义计算完成事件 public event EventHandler<CalcCompletedArgs> CalculationCompleted; public override ISomeTable Calculate(string s) { var someTable1 = new SomeTableImpl(); var sharedData = GenerateSharedData(someTable1); // 触发事件,传递共享数据 OnCalculationCompleted(new CalcCompletedArgs { SharedData = sharedData, Input = s }); return someTable1; } protected virtual void OnCalculationCompleted(CalcCompletedArgs e) { CalculationCompleted?.Invoke(this, e); } private Dictionary<string, object> GenerateSharedData(ISomeTable table) { return new() { { "key", "value" } }; } } public class SomeClass2 : SomeBaseClass { private ISomeTable _cachedResult; // 订阅SomeClass1的事件 public void SubscribeToCalc(SomeClass1 class1) { class1.CalculationCompleted += Class1_CalcCompleted; } // 事件回调:接收数据并执行自身逻辑 private void Class1_CalcCompleted(object sender, CalcCompletedArgs e) { var sharedData = e.SharedData; _cachedResult = ExecuteCalc(e.Input, sharedData); } // 内部计算方法 private ISomeTable ExecuteCalc(string s, Dictionary<string, object> sharedData) { var someTable2 = new SomeTableImpl(); // ... 写入使用sharedData的逻辑 return someTable2; } // 保持原有Calculate方法签名 public override ISomeTable Calculate(string s) { return _cachedResult ?? throw new InvalidOperationException("等待SomeClass1计算完成"); } } // 触发源处的执行逻辑 var class1 = new SomeClass1(); var class2 = new SomeClass2(); class2.SubscribeToCalc(class1); // 执行SomeClass1后,自动触发SomeClass2的计算 class1.Calculate("input"); var result2 = class2.Calculate("input");
注意事项
- 如果是多线程场景,要注意共享数据的线程安全,比如使用
ConcurrentDictionary或者加锁机制。 - 依赖注入方式适合简单场景,代码清晰易维护;事件机制适合需要解耦的复杂场景。
内容的提问来源于stack exchange,提问作者axcelenator
相关产品推荐
相关产品推荐

