异步素数计算

use*_*650 -3 c# wpf asynchronous async-await

我有以下计算第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);
            }
Run Code Online (Sandbox Code Playgroud)

我想在wpf应用程序中调用此函数,在其中输入数字,然后使用按钮调用该函数:

private void one_Click(object sender, RoutedEventArgs e)
        {
            answer = FindPrimeNumber(Convert.ToInt64(txtprime.Text));
            MessageBox.Show(answer.ToString());
        }
Run Code Online (Sandbox Code Playgroud)

这很好用,但是当您开始输入一百万个数字时,它会变慢并阻塞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);
    }
Run Code Online (Sandbox Code Playgroud)

异步按钮:

 private async void two_Click(object sender, RoutedEventArgs e)
        {
            answer = await Async_FindPrimeNumber(Convert.ToInt64(txtprime.Text));
            MessageBox.Show(answer.ToString());
        }
Run Code Online (Sandbox Code Playgroud)

但是用户界面仍然被阻止。如何使此方法异步?谢谢

Ste*_*ary 5

正如其他人指出的那样,编译器将向您发出警告,告诉您确切的问题所在。

要将与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());
}
Run Code Online (Sandbox Code Playgroud)