我有以下函数来计算第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仍然被阻止。如何使此方法异步? 谢谢
答案 0 :(得分:4)
正如其他人所说,编译器会给你一个警告,告诉你究竟出了什么问题。
要将UI线程中的CPU绑定工作推送到线程池,您可以使用self.id = self.id + id
。请注意pack();
应该用于调用方法,而不是实现方法:
Task.Run
答案 1 :(得分:0)
最简单的方法是将函数的整个主体包裹在Task.Run
中。输入后,async
函数将同步运行,直到达到第一个await
。
此外,在事件处理程序中,将该函数的整个主体包装在try
- catch
中,async void
无法像通常的同步代码那样将异常传播给调用者
答案 2 :(得分:-1)
您可以使您的方法像
一样异步 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);
});
}