我有一个关于C# .NET应用程序中异步\等待的问题。实际上,我正在尝试在基于Kinect的应用程序中解决此问题,但为了帮助我说明,我已经构建了这个类比例子:
假设我们有一个名为timer1的计时器,它设置了Timer1_Tick事件。现在,我对该事件采取的唯一操作是使用当前日期时间更新UI。
这很简单,我的用户界面每隔几百分之一秒更新一次,我可以愉快地观察时间的流逝。
现在想象一下,我还想在同样的方法中计算前500个素数:
这是我遇到的问题。计算质数的密集方法阻止了事件处理程序的运行 - 因此我的计时器文本框现在每30秒才更新一次。
我的问题是,如何在遵守以下规则的同时解决这个问题:
任何帮助都将不胜感激 - 我非常愿意接受正确的答案 :)
假设我们有一个名为timer1的计时器,它设置了Timer1_Tick事件。现在,我对该事件采取的唯一操作是使用当前日期时间更新UI。
private void Timer1_Tick(object sender, EventArgs e)
{
txtTimerValue.Text = DateTime.Now.ToString("hh:mm:ss.FFF", CultureInfo.InvariantCulture);
}
这很简单,我的用户界面每隔几百分之一秒更新一次,我可以愉快地观察时间的流逝。
现在想象一下,我还想在同样的方法中计算前500个素数:
private void Timer1_Tick(object sender, EventArgs e)
{
txtTimerValue.Text = DateTime.Now.ToString("hh:mm:ss.FFF", CultureInfo.InvariantCulture);
List<int> primeNumbersList = WorkOutFirstNPrimeNumbers(500);
PrintPrimeNumbersToScreen(primeNumbersList);
}
private List<int> WorkOutFirstNPrimeNumbers(int n)
{
List<int> primeNumbersList = new List<int>();
txtPrimeAnswers.Clear();
int counter = 1;
while (primeNumbersList.Count < n)
{
if (DetermineIfPrime(counter))
{
primeNumbersList.Add(counter);
}
counter++;
}
return primeNumbersList;
}
private bool DetermineIfPrime(int n)
{
for (int i = 2; i < n; i++)
{
if (n % i == 0)
{
return false;
}
}
return true;
}
private void PrintPrimeNumbersToScreen(List<int> primeNumbersList)
{
foreach (int primeNumber in primeNumbersList)
{
txtPrimeAnswers.Text += String.Format("The value {0} is prime \r\n", primeNumber);
}
}
这是我遇到的问题。计算质数的密集方法阻止了事件处理程序的运行 - 因此我的计时器文本框现在每30秒才更新一次。
我的问题是,如何在遵守以下规则的同时解决这个问题:
- 我需要我的UI计时器文本框像以前一样平滑,可能通过将密集的质数计算推送到不同的线程来实现。我猜,这将使事件处理程序像以前一样频繁运行,因为阻塞语句不再存在。
- 每次质数计算函数完成后,都会将其结果写入屏幕(使用我的PrintPrimeNumbersToScreen()函数),并且立即重新启动,以防万一这些质数发生变化。
任何帮助都将不胜感激 - 我非常愿意接受正确的答案 :)
更新:我非常感谢@sstan能够提供一个简洁的解决方案来解决这个问题。然而,我在将其应用于我的真实基于Kinect的情况时遇到了困难。由于我有点担心让这个问题变得太具体,所以我已经在这里发布了后续问题: Kinect Frame Arrived Asynchronous。