在多线程 UI 程序中获取 System.ArgumentOutOfRangeException
Getting System.ArgumentOutOfRangeException in Multithreaded UI program
我正在研究 C# 5.0 in a Nutshell 一书中的示例。基本上,该示例所做的是异步计算指定范围内的素数并更新 UI。当我 运行 来自控制台的代码时,它 运行 可以正常输出以下内容:
然而,当我 运行 来自 GUI 的代码时,我在控制台上收到以下错误(因为该项目是控制台应用程序):
Unhandled Exception: System.ArgumentOutOfRangeException: Specified
argument was out of the range of valid values. Parameter name: count
at System.Linq.Enumerable.Range(Int32 start, Int32 count) at
Multithreading.TestUi.b__8(Int32 n) in
TestUI.cs:line 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();
}
}
}
提前致谢。
你的问题来自 Enumerable.Range(2, (int)Math.Sqrt(n) - 1)
,n
在你的第一个 运行 上等于 0
所以你得到 Enumerable.Range(2, -1)
这将抛出一个范围异常。
这与在 GUI 中 运行ning 无关,您在从控制台到 GUI 时犯了某种错误。在 GetPrimeCountAsyn
中的控制台版本中放置一个断点,要么 start
传递的值不是 0,要么你没有 Enumerable.Range(2, (int)Math.Sqrt(n) - 1)
我正在研究 C# 5.0 in a Nutshell 一书中的示例。基本上,该示例所做的是异步计算指定范围内的素数并更新 UI。当我 运行 来自控制台的代码时,它 运行 可以正常输出以下内容:
然而,当我 运行 来自 GUI 的代码时,我在控制台上收到以下错误(因为该项目是控制台应用程序):
Unhandled Exception: System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: count
at System.Linq.Enumerable.Range(Int32 start, Int32 count) at Multithreading.TestUi.b__8(Int32 n) in TestUI.cs:line 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();
}
}
}
提前致谢。
你的问题来自 Enumerable.Range(2, (int)Math.Sqrt(n) - 1)
,n
在你的第一个 运行 上等于 0
所以你得到 Enumerable.Range(2, -1)
这将抛出一个范围异常。
这与在 GUI 中 运行ning 无关,您在从控制台到 GUI 时犯了某种错误。在 GetPrimeCountAsyn
中的控制台版本中放置一个断点,要么 start
传递的值不是 0,要么你没有 Enumerable.Range(2, (int)Math.Sqrt(n) - 1)