2015-11-17 57 views
-3

我有以下函数计算第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()); 
     } 

这工作得很好,但是当你开始从100万输入的数字。这得慢,并阻止用户界面。

因此,我想使按钮异步,以便它不会阻止用户界面。

这是我尝试:

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仍然受阻。我怎样才能使这种方法异步? 谢谢

+3

您当前的代码已经产生警告正好说明你做错了什么,为什么你的“异步”操作”不是个实际上是异步的。 – Servy

+0

你需要使用一个线程。 –

回答

-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); 
     }); 
    } 
+1

我会建议最好是调用方法'FindPrimeNumber'并从'Task1Run'内调用'button1_Click',但这只是挑剔。 –

0

最简单的做法是将函数的整个主体包装在Task.Run中。输入时,async功能同步运行,直到达到第一个await

此外,在事件处理程序,换行功能的整个主体中try - catchasync void是不能够传播例外呼叫者的方式正常同步码将的。

3

正如其他人指出,编译器会给你一个警告信息,告诉你什么是错的。

要将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()); 
}