我正在研究书籍C# 5.0 in a Nutshell中的一个例子。基本上,该例子的作用是异步计算指定范围内的素数并更新UI。当我从控制台运行代码时,它运行正常,输出如下:
然而,当我从GUI运行代码时,我在控制台上收到错误以下错误(因为项目是控制台应用程序):
未处理的异常:System.ArgumentOutOfRangeException:已指定 参数超出了有效值的范围。参数名称:计数
在System.Linq.Enumerable.Range(Int32 start,Int32 count)at Multithreading.TestUi.b__8(Int32 n)in TestUI.cs:第38行
那么,我错过了什么?我该如何解决这个问题?
以下是生成错误的代码:
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace Multithreading
{
class TestUi:Window
{
private Button _button = new Button{Content = "Go"};
private TextBlock _results = new TextBlock();
public TestUi()
{
var panel = new StackPanel();
panel.Children.Add(_button);
panel.Children.Add(_results);
Content = panel;
_button.Click += (sender, args) => Go();
}
async void Go()
{
_button.IsEnabled = false; //disable the button while the calculation is proceeding.
for (int i = 0; i < 10; i++)
{
int result = await GetPrimeCountAsyn(i*1000000, 1000000); //asynchronously calculate the prime numbers within the range
_results.Text += String.Format("There are {0} primes between {1} and {2}{3}", result , (i * 100000), ((i+1) * 100000 - 1), Environment.NewLine);
}
_button.IsEnabled = true;
}
Task<int> GetPrimeCountAsyn(int start, int count)
{
int p = Enumerable.Range(start, count).Count(
n => Enumerable.Range(2, (int) Math.Sqrt(n) - 1).All(i => n%i > 0));
return Task.Run(() => p);
}
[STAThread]
static void Main()
{
Application app = new Application();;
app.Run(new TestUi());
Console.ReadLine();
}
}
}
提前致谢。
答案 0 :(得分:5)
您的问题来自Enumerable.Range(2, (int)Math.Sqrt(n) - 1)
,n
在您第一次运行时将等于0
,因此您获得的Enumerable.Range(2, -1)
会超出范围异常。
这与在GUI中运行无关,你从控制台到GUI发生了某种错误。在GetPrimeCountAsyn
中的控制台版本中添加断点,start
传递的值不是0,或者您没有Enumerable.Range(2, (int)Math.Sqrt(n) - 1)