在多线程 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)