C# Battlefield 4插件如何等待响应事件完成后继续执行逻辑
解决方案
你可以通过TaskCompletionSource实现异步等待事件触发的逻辑,完全满足你不耦合事件和命令执行流程、无需修改事件原有签名的需求。TaskCompletionSource的作用就是把外部回调/事件触发的逻辑封装成可等待的Task,刚好匹配你的场景。
实现步骤
- 首先声明线程安全的字典存储待完成的命令对应等待源,避免多线程冲突
- 将原命令执行方法改为异步方法,每个命令发送前创建对应等待源,异步等待完成
- 在每个响应事件的末尾,匹配到对应等待源并标记为完成,即可唤醒后续命令执行
代码示例
首先添加类成员变量:
// 存储命令名对应等待源,线程安全 private readonly ConcurrentDictionary<string, TaskCompletionSource> _pendingCommandSources = new();
改造命令执行方法:
// 改为异步方法,上层调用时可直接await,不会阻塞插件主线程 private async Task PerformProconTasks(params string[] actions) { foreach(var action in actions) { var command = action.Split(' '); var commandName = command[0]; // 为当前命令创建等待源,RunContinuationsAsynchronously避免同步阻塞事件线程 var completionSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); _pendingCommandSources.TryAdd(commandName, completionSource); try { RegisterEvents(this.GetType().Name, InvocationDictionary[commandName]); ProconPluginEXT.ExecuteCommand(this, command); // 等待事件触发,增加超时逻辑避免服务器无响应时永久阻塞 var timeoutTask = Task.Delay(TimeSpan.FromSeconds(30)); var finishedTask = await Task.WhenAny(completionSource.Task, timeoutTask); if (finishedTask == timeoutTask) { // 自定义超时处理逻辑,比如输出错误日志 this.ExecuteCommand("procon.protected.pluginconsole.write", $"^1Command {commandName} execution timed out"); } } finally { // 执行结束清理等待源,避免内存泄漏 _pendingCommandSources.TryRemove(commandName, out _); } } }
修改事件处理逻辑,仅新增一行完成通知代码即可,无需修改原有事件逻辑:
public override void On3dSpotting(bool isEnabled) { // 原有事件逻辑完全保留 this.ExecuteCommand("procon.protected.pluginconsole.write", "^6Hello from the other side!"); // 新增:匹配到对应命令的等待源,标记为完成,唤醒命令队列继续执行 if (_pendingCommandSources.TryRemove("vars.3dSpotting", out var source)) { source.SetResult(); } }
注意事项
- 如果存在同一条命令并行发送的场景,可将字典key改为命令名+唯一请求ID的组合,避免匹配混乱
- 禁止使用
.Wait()/.Result等同步等待方式,会直接卡死插件主线程,必须全程使用async/await异步等待 - 如果需要获取事件返回的参数,只需将
TaskCompletionSource改为泛型版本,比如TaskCompletionSource<bool>,SetResult时传入事件参数,await时即可直接拿到返回值 - 该方案完全解耦了事件和命令执行流程,命令流转逻辑全部在
PerformProconTasks中维护,事件仅承担完成通知的作用,没有额外耦合
内容的提问来源于stack exchange,提问作者KodenameYT
相关产品推荐
相关产品推荐

