通知主UI线程中的System.Timer



有没有一种方法可以通知主GUI线程System.TimerElapsed方法结束?

我的真实情况是:我在业务逻辑中有一个类使用System.Timer来执行例程操作,因为计时器使用池线程,所以我不能使用在GUI中使用的事件,因为这些事件将在不同的GUI线程中调用。我需要的是某种通知,通知我的GUI线程Elapsed方法已经完成,然后我可以更新GUI字段。有可能吗?

我想到的一个解决方案是使用System.Windows.Forms.Timer,在它的Tick方法中,我在异步等待中完成所有操作,但我不太喜欢它,因为我想让GUI没有业务逻辑工作,我想了解是否有其他可能的方法来解决我的这种情况。

您可以考虑使用IProgress<T>抽象从业务层通知UI层。业务层类将接受由UI层提供的IProgress<T>实现。任何时候需要将通知传递到UI层,业务层都会调用Report方法。这个接口已经有一个内置的实现Progress<T>类,只要该类在UI线程上实例化,它就会自动将通知封送至UI线程。示例:

class BusinessLayer
{
public void Initialize (IProgress<string> progress) { /* ... */ }
}
public Form1()
{
InitializeComponent();
var progress = new Progress<string>(message =>
{
TextBox1.AppendText($"{message}rn");
});
BusinessLayer.Initialize(progress);
}

您可以根据需要自由选择IProgress<T>的类型T。它可以是简单的string,也可以是复杂的ValueTuple,比如(int, string, bool),或者是自定义类型等。

需要注意的是通知的频率。如果业务层Report过于频繁,UI线程可能会阻塞并变得无响应。

非常感谢大家的回答。

我听从了@Teodoro的建议,这正是我想要的,出于我的需要,我将IProgress<T>设置为这样:

public class IA_Routine
{
IA_Core Core;
Timer TimeRoutine;
IProgress<object> ProgressEnd;
public event EventHandler NotifyEndElapsedRoutine;
public IA_Routine(IA_Core core)
{
Core = core;
ProgressEnd = new Progress<object>(obj =>
{
FuncNotifyElapsedEnd();
});
TimeRoutine = new Timer();
TimeRoutine.AutoReset = true;
TimeRoutine.Interval = Core.TimingRoutine;
TimeRoutine.Elapsed += TimeRoutine_Elapsed;
}
internal void StartRoutine()
{
TimeRoutine.Start();
}
private void TimeRoutine_Elapsed(object sender, ElapsedEventArgs e)
{
//-- routine functions
//--
//--
ProgressEnd.Report(null);
}
void FuncNotifyElapsedEnd()
{
NotifyEndElapsedRoutine?.Invoke(this, EventArgs.Empty);
}
}

我指定TimerSystem.Timers,并且类实例是在UI线程中创建的,我不知道这是否是使用IProgres<T>的最佳方式,但同时它可以按我的意愿工作,再次感谢

最新更新