异步素数计算
本文关键字:计算 异步 | 更新日期: 2023-09-27 18:22:13
我有以下函数来计算第n个素数(而不是我的函数):
public long FindPrimeNumber(long n)
{
int count = 0;
long a = 2;
while (count < n)
{
long b = 2;
int prime = 1;// to check if found a prime
while (b * b <= a)
{
if (a % b == 0)
{
prime = 0;
break;
}
b++;
}
if (prime > 0)
count++;
a++;
}
return (--a);
}
我想在wpf应用程序中调用这个函数,在这里输入一个数字,然后用按钮调用该函数:
private void one_Click(object sender, RoutedEventArgs e)
{
answer = FindPrimeNumber(Convert.ToInt64(txtprime.Text));
MessageBox.Show(answer.ToString());
}
这很好,但当你开始输入一百万的数字时,速度会变慢,并会阻塞UI。
因此,我想使按钮异步,这样它就不会阻塞UI。
我就是这样尝试的:
public async Task<long> Async_FindPrimeNumber(long n)
{
int count = 0;
long a = 2;
while (count < n)
{
long b = 2;
int prime = 1;// to check if found a prime
while (b * b <= a)
{
if (a % b == 0)
{
prime = 0;
break;
}
b++;
}
if (prime > 0)
count++;
a++;
}
return (--a);
}
异步按钮:
private async void two_Click(object sender, RoutedEventArgs e)
{
answer = await Async_FindPrimeNumber(Convert.ToInt64(txtprime.Text));
MessageBox.Show(answer.ToString());
}
但是UI仍然被阻止。如何使此方法异步?感谢
正如其他人所指出的,编译器会给你一个警告,告诉你到底出了什么问题。
要将绑定CPU的工作从UI线程推送到线程池中,可以使用Task.Run
。请注意,Task.Run
应用于调用方法,而不是实现它们:
private async void two_Click(object sender, RoutedEventArgs e)
{
var input = Convert.ToInt64(txtprime.Text);
answer = await Task.Run(() => FindPrimeNumber(input));
MessageBox.Show(answer.ToString());
}
最简单的方法是将函数的整个主体封装在Task.Run
中。输入后,async
功能将同步运行,直到达到第一个await
。
此外,在事件处理程序中,将该函数的整个主体包装在try
-catch
中,async void
无法像普通同步代码那样向调用方传播异常。
您可以使您的方法像一样异步
private async void button1_Click(object sender, EventArgs e)
{
var answer = await FindPrimeNumberAsync(Convert.ToInt64(txtprime.Text));
MessageBox.Show(answer.ToString());
}
public Task<long> FindPrimeNumberAsync(long n)
{
return Task.Run<long>(()=>
{
int count = 0;
long a = 2;
while (count < n)
{
long b = 2;
int prime = 1;// to check if found a prime
while (b * b <= a)
{
if (a % b == 0)
{
prime = 0;
break;
}
b++;
}
if (prime > 0)
count++;
a++;
}
return (--a);
});
}