在主线程 UI 中通知 System.Timer
Notify System.Timer in main UI thread
有没有办法通知主 GUI 线程 System.Timer
的 Elapsed
方法结束?
我的真实情况是这样的:
我在业务逻辑中有一个 class,它使用 System.Timer
来执行例行操作,因为计时器使用池线程 我不能使用我在 GUI 中使用的事件,因为这些事件将在不同的 GUI 线程。
我需要的是某种通知,通知我的 GUI 线程 Elapsed
方法已完成,然后我可以更新 GUI 字段。
可能吗?
我想到的一个解决方案是使用 System.Windows.Forms.Timer
,在它的 Tick
方法中,我在异步等待中执行所有操作,但我不太喜欢它,因为我想在没有业务逻辑工作的情况下离开 GUI,我想了解是否有其他可能的方法来解决我的这种情况。
您可以考虑使用 IProgress<T>
abstraction. The business layer class would accept a IProgress<T>
implementation that would be provided by the UI layer. Any time a notification will need to be passed to the UI layer, the business layer will invoke the Report
method. There is already a built-in implementation of this interface, the Progress<T>
class 从业务层通知 UI 层,它会自动将通知编组到 UI 线程,前提是class 在 UI 线程上实例化。示例:
class BusinessLayer
{
public void Initialize (IProgress<string> progress) { /* ... */ }
}
public Form1()
{
InitializeComponent();
var progress = new Progress<string>(message =>
{
TextBox1.AppendText($"{message}\r\n");
});
BusinessLayer.Initialize(progress);
}
您可以根据需要自由选择IProgress<T>
类型T
。它可以是像 string
这样简单的东西,也可以是像 (int, string, bool)
这样复杂的 ValueTuple
或自定义类型等
需要注意的是通知的频率。如果业务层 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);
}
}
我指定Timer
是一个System.Timers
而class实例是在UI
线程中创建的,不知道是不是最好的IProgres<T>
的使用方法,但同时它按我的意愿工作,再次感谢
有没有办法通知主 GUI 线程 System.Timer
的 Elapsed
方法结束?
我的真实情况是这样的:
我在业务逻辑中有一个 class,它使用 System.Timer
来执行例行操作,因为计时器使用池线程 我不能使用我在 GUI 中使用的事件,因为这些事件将在不同的 GUI 线程。
我需要的是某种通知,通知我的 GUI 线程 Elapsed
方法已完成,然后我可以更新 GUI 字段。
可能吗?
我想到的一个解决方案是使用 System.Windows.Forms.Timer
,在它的 Tick
方法中,我在异步等待中执行所有操作,但我不太喜欢它,因为我想在没有业务逻辑工作的情况下离开 GUI,我想了解是否有其他可能的方法来解决我的这种情况。
您可以考虑使用 IProgress<T>
abstraction. The business layer class would accept a IProgress<T>
implementation that would be provided by the UI layer. Any time a notification will need to be passed to the UI layer, the business layer will invoke the Report
method. There is already a built-in implementation of this interface, the Progress<T>
class 从业务层通知 UI 层,它会自动将通知编组到 UI 线程,前提是class 在 UI 线程上实例化。示例:
class BusinessLayer
{
public void Initialize (IProgress<string> progress) { /* ... */ }
}
public Form1()
{
InitializeComponent();
var progress = new Progress<string>(message =>
{
TextBox1.AppendText($"{message}\r\n");
});
BusinessLayer.Initialize(progress);
}
您可以根据需要自由选择IProgress<T>
类型T
。它可以是像 string
这样简单的东西,也可以是像 (int, string, bool)
这样复杂的 ValueTuple
或自定义类型等
需要注意的是通知的频率。如果业务层 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);
}
}
我指定Timer
是一个System.Timers
而class实例是在UI
线程中创建的,不知道是不是最好的IProgres<T>
的使用方法,但同时它按我的意愿工作,再次感谢