You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让DAwaiter持续检测公共变量值?支持多变量条件吗?

问题描述

需要实现一个DAwaiter方法,持续检测已实例化对象的特定公共bool变量值,直到变量变为指定值(或满足组合条件),而非传递变量副本。当前实现中DAwaiter仅获取变量初始值,无法响应后续变化,同时希望该方法能支持多变量组合条件(如XDone && YDone == true)。

解决方案

1. 实现持续检测单个变量

核心问题是直接传递bool值会产生值类型副本,导致DAwaiter无法获取变量的最新状态。改用Func<bool>委托可以解决这个问题——委托会在每次检查时重新执行lambda表达式,从而获取目标变量的实时值。

修改后的DAwaiter方法:

internal bool DAwaiter(Func<bool> condition, int delay, CancellationToken ct)
{
    Logger("Beginning DAwaiter");
    while (!condition())
    {
        Logger($"awaiting... Current state: {condition()}");
        if (ct.IsCancellationRequested)
        {
            Logger("Cancelled DAwaiter.");
            return false;
        }
        Thread.Sleep(delay);
    }
    Logger("DAwaiter finished true.");
    return true;
}

调用单个变量时,传入获取变量的lambda表达式:

// 等待Homed变为true
if (!DAwaiter(() => Homed, 250, cts.Token)) { return; }

2. 扩展支持多变量组合条件

由于使用了Func<bool>委托,无需修改DAwaiter方法,直接传入组合条件的lambda表达式即可:

// 等待XDone和YDone同时为true
if (!DAwaiter(() => XDone && YDone, 250, cts.Token)) { return; }

完整关键代码示例

public class ArduinoComms 
{
    // ... 原有成员变量、SerialPort初始化等代码 ...

    public void Home()
    {
        Homed = false;
        Ready = false;
        XDone = false;
        YDone = false;
        Logger("Beginning home");
        //WriteMyCommand(2); 发送归位命令到Arduino
        if (!DAwaiter(() => Homed, 250, cts.Token)) { return; }
        
        Logger("finished home, beginning backoff");
        XDone = false;
        YDone = false;
        //WriteMyCommand(0, backoff);
        //WriteMyCommand(1, backoff);
        if (!DAwaiter(() => XDone && YDone, 250, cts.Token)) { return; }

        Logger("Finished home");
        Ready = true;
    }

    internal bool DAwaiter(Func<bool> condition, int delay, CancellationToken ct)
    {
        Logger("Beginning DAwaiter");
        while (!condition())
        {
            Logger($"awaiting... Current state: {condition()}");
            if (ct.IsCancellationRequested)
            {
                Logger("Cancelled DAwaiter.");
                return false;
            }
            Thread.Sleep(delay);
        }
        Logger("DAwaiter finished true.");
        return true;
    }

    // ... 原有DataReceived事件处理、Logger等代码 ...
}

额外优化建议

如果涉及UI线程,Thread.Sleep会阻塞线程,建议改用异步版本的等待方法,避免UI卡顿:

internal async Task<bool> DAwaiterAsync(Func<bool> condition, int delay, CancellationToken ct)
{
    Logger("Beginning DAwaiter");
    while (!condition())
    {
        Logger($"awaiting... Current state: {condition()}");
        if (ct.IsCancellationRequested)
        {
            Logger("Cancelled DAwaiter.");
            return false;
        }
        await Task.Delay(delay, ct);
    }
    Logger("DAwaiter finished true.");
    return true;
}

调用时需将Home改为异步方法:

public async Task Home()
{
    // ... 原有初始化代码 ...
    if (!await DAwaiterAsync(() => Homed, 250, cts.Token)) { return; }
    // ... 后续逻辑 ...
}

内容的提问来源于stack exchange,提问作者Cameron Hadland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:27:07