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

C#如何将ref修饰的int变量传入窗口 实现跨窗口修改控制线程循环退出

你遇到的核心问题:C# 中值类型的 ref 参数只能在当前方法的作用域内使用,无法存储为类的成员变量在后续其他方法(比如按钮点击、定时器回调)中使用,所以你原本直接传 ref int 的思路走不通,有两种成熟的实现方案:

方案1:用引用类型包装int值

值类型本身不保留引用,你可以把int封装到一个引用类型的包装类中,这样所有地方操作的都是同一个对象内的值,天然同步:
首先定义包装类:

public class IntWrapper
{
    public int Value;
}

修改原有业务代码:

// 原来的int stop替换为包装类实例
public IntWrapper stop = new IntWrapper { Value = 0 };
public void main()
{
    Thread thrDoStuff = new Thread(()=> dostuff(stop));
    testWindow window = new testWindow(stop);
}

public void dostuff(IntWrapper stop)
{
    while (true)
    {
        // 跨线程读取用Volatile.Read保证拿到最新值,避免CPU缓存导致的读取延迟
        if (Volatile.Read(ref stop.Value) != 0)
        {
            break;
        }
    }
    // 退出循环后的其他逻辑
} 

修改窗口代码:

public readonly DispatcherTimer Start = new DispatcherTimer();
// 类成员存储包装类实例
private IntWrapper _stop;
public testWindow (IntWrapper stop )
{
    InitializeComponent();
    _stop = stop;
        
    Start.Interval = TimeSpan.FromMilliseconds(100);
    Start.Tick += workloop;
    Start.IsEnabled = true;
 }

private void buttonClick(object sender, RoutedEventArgs e)
{
    // 直接修改包装类的Value属性,同步到所有引用位置
    Volatile.Write(ref _stop.Value, 1);
}

private void workloop(object sender, EventArgs e)
{
    Start.IsEnabled = false;
    Volatile.Write(ref _stop.Value, 1);
}  

注:Volatile 类属于 System.Threading 命名空间,需要提前引入

方案2:使用.NET原生的CancellationTokenSource(更推荐)

.NET 专门提供了 CancellationTokenSource 用于多线程/任务的取消场景,是官方推荐的标准实现,不需要自己处理内存可见性等问题:
修改原有业务代码:

public CancellationTokenSource cts = new CancellationTokenSource();
public void main()
{
    Thread thrDoStuff = new Thread(()=> dostuff(cts.Token));
    testWindow window = new testWindow(cts);
}

public void dostuff(CancellationToken token)
{
    while (true)
    {
        if (token.IsCancellationRequested)
        {
            break;
        }
    }
    // 用完记得释放资源
    cts.Dispose();
} 

修改窗口代码:

public readonly DispatcherTimer Start = new DispatcherTimer();
private CancellationTokenSource _cts;
public testWindow (CancellationTokenSource cts )
{
    InitializeComponent();
    _cts = cts;
        
    Start.Interval = TimeSpan.FromMilliseconds(100);
    Start.Tick += workloop;
    Start.IsEnabled = true;
 }

private void buttonClick(object sender, RoutedEventArgs e)
{
    // 调用Cancel方法即可触发所有持有Token的位置收到取消通知
    _cts.Cancel();
}

private void workloop(object sender, EventArgs e)
{
    Start.IsEnabled = false;
    _cts.Cancel();
}  

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:36:05