C# 能否将带参数的函数作为委托传递以动态修改WinForms Timer回调
问题根源
你现在的写法错误本质是:searchFunc1(thisBuffer, "abc") 是直接执行方法得到bool返回值,并不是传递方法本身/委托,自然无法作为委托参数传入。
实现方案
你要的「提前绑定参数、传递可执行的方法」需求可以通过C#的lambda闭包实现,不需要自己定义委托,用.NET内置的Func<bool>泛型委托即可。
第一步:调整原有字段和回调逻辑
// 替换原来的MyFunction委托定义,直接用内置Func<bool>,不需要带参数,参数会被闭包捕获 static Func<bool> timerFunction; static bool pollVariable; static int timerCount; System.Windows.Forms.Timer myTimer; // 初始化Timer代码保持不变 myTimer = new System.Windows.Forms.Timer(); myTimer.Interval = 100; myTimer.Tick += new EventHandler(TimerElapsed); private void TimerElapsed(object sender, EventArgs e) { timerCount++; // 直接调用无参数的委托,参数已经在绑定的时候捕获好了 pollVariable = timerFunction(); }
第二步:修改轮询方法
注意:你原有代码里的while循环会阻塞UI线程,Winform的Timer回调跑在UI线程,阻塞后Tick事件根本不会触发,同时要修正判断条件里的赋值笔误
推荐改成异步实现避免UI卡死:
// 改成异步方法,不会阻塞UI private static async Task PollVariableWithTimeout(Func<bool> checkFunc, int timeout) { timerFunction = checkFunc; timerCount = 0; pollVariable = false; myTimer.Start(); while(myTimer.Enabled) { // 每次循环等待100ms,和Timer间隔一致,不会卡UI await Task.Delay(100); // 注意是==判断不是=赋值 if (timerCount >= timeout || pollVariable == true) { myTimer.Stop(); break; } } }
第三步:调用方式
用lambda表达式捕获你要传入的参数,直接生成符合Func<bool>要求的委托:
// 传入绑定好参数的方法,和你期望的调用逻辑一致 _ = PollVariableWithTimeout(() => searchFunc1(thisBuffer, "abc"), 200); _ = PollVariableWithTimeout(() => searchFunc2(thatBuffer, "123"), 500);
其他优化建议
如果不需要复用Timer的话,其实可以完全抛弃Timer,直接在异步方法里做轮询,逻辑更简单也避免全局变量的线程安全问题:
private static async Task<bool> PollVariableWithTimeout(Func<bool> checkFunc, int timeout, int interval = 100) { int count = 0; while(count * interval < timeout) { if(checkFunc()) { return true; } await Task.Delay(interval); count++; } return false; } // 调用 bool result = await PollVariableWithTimeout(() => searchFunc1(thisBuffer, "abc"), 200);
内容的提问来源于stack exchange,提问作者Colm Murphy
相关产品推荐
相关产品推荐

