gpt4 book ai didi

c# - 多个并发操作的 UI 更新

转载 作者:行者123 更新时间:2023-12-02 13:42:02 26 4
gpt4 key购买 nike

我正在使用 National Instruments Daqmx 开发一个 C# 应用程序,用于在某些硬件上执行测量。

我的设置由多个检测器组成,我必须在设定的时间段内从中获取数据,同时使用这些数据更新我的 UI。

 public class APD : IDevice
{
// Some members and properties go here, removed for clarity.

public event EventHandler ErrorOccurred;
public event EventHandler NewCountsAvailable;

// Constructor
public APD(
string __sBoardID,
string __sPulseGenCtr,
string __sPulseGenTimeBase,
string __sPulseGenTrigger,
string __sAPDTTLCounter,
string __sAPDInputLine)
{
// Removed for clarity.
}

private void APDReadCallback(IAsyncResult __iaresResult)
{
try
{
if (this.m_daqtskRunningTask == __iaresResult.AsyncState)
{
// Get back the values read.
UInt32[] _ui32Values = this.m_rdrCountReader.EndReadMultiSampleUInt32(__iaresResult);

// Do some processing here!

if (NewCountsAvailable != null)
{
NewCountsAvailable(this, new EventArgs());
}

// Read again only if we did not yet read all pixels.
if (this.m_dTotalCountsRead != this.m_iPixelsToRead)
{
this.m_rdrCountReader.BeginReadMultiSampleUInt32(-1, this.m_acllbckCallback, this.m_daqtskAPDCount);
}
else
{
// Removed for clarity.
}
}
}
catch (DaqException exception)
{
// Removed for clarity.
}
}


private void SetupAPDCountAndTiming(double __dBinTimeMilisec, int __iSteps)
{
// Do some things to prepare hardware.
}

public void StartAPDAcquisition(double __dBinTimeMilisec, int __iSteps)
{
this.m_bIsDone = false;

// Prepare all necessary tasks.
this.SetupAPDCountAndTiming(__dBinTimeMilisec, __iSteps);

// Removed for clarity.

// Begin reading asynchronously on the task. We always read all available counts.
this.m_rdrCountReader.BeginReadMultiSampleUInt32(-1, this.m_acllbckCallback, this.m_daqtskAPDCount);
}

public void Stop()
{
// Removed for clarity.
}
}

表示检测器的对象基本上调用 BeginXXX 操作,并带有保存 EndXXX 的回调,同时还会触发一个指示数据可用的事件。

我的 UI 表单中最多有 4 个这样的检测器对象作为成员。我按顺序调用所有这些方法的 Start() 方法来开始测量。这有效,并且 NewCountsAvailable 事件对所有四个都触发。

由于我的实现的性质,BeginXXX 方法是在 UI 线程上调用的,并且回调和事件也在该 UI 线程上。因此,我无法在 UI 线程内使用某种 while 循环来不断用新数据更新我的 UI,因为事件不断触发(我尝试过这个)。我也不想在四个 NewCountsAvailable 事件处理程序中使用某种 UpdateUI() 方法,因为这会给我的系统带来太多负载。

由于我是 C# 线程编程的新手,所以我现在陷入困境;

1)处理这种情况的“正确”方法是什么?2)我的检测器对象的实现是否合理?我应该从另一个线程调用这四个检测器对象的 Start() 方法吗?3) 我可以使用计时器每隔几百毫秒更新一次 UI,而不管 4 个检测器对象在做什么?

我真的不知道!

最佳答案

我会使用一个简单的延迟更新系统。

1) 工作线程通过引发事件发出“数据就绪”信号

2) UI 线程监听事件。当它被接收时,它只是设置一个“数据需要更新”标志并返回,因此对事件本身进行最少的处理。

3) UI 线程使用计时器(或位于 Application.Idle 事件上)来检查“数据需要更新”标志,并在必要时更新 UI。很多情况下,UI 只需要每秒更新一两次,因此不需要消耗大量 CPU 时间。

这允许 UI 始终继续正常运行(与用户保持交互),但在某些数据准备就绪的短时间内,它会显示在 UI 中。

此外,对于良好的 UI 而言,最重要的是,此方法可用于允许触发多个“数据就绪”事件并将其滚动到单个 UI 更新中。这意味着,如果 10 条数据连续完成,UI 会更新一次,而不是随着 UI 重绘(不必要地)10 次而使窗口闪烁几秒钟。

关于c# - 多个并发操作的 UI 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1351702/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com