【发布时间】:2015-10-02 04:54:16
【问题描述】:
我正在制作一个小程序来练习使用 WPF 和 Async/Await 进行多线程处理,该程序的作用是:
- 找出两个数字“a”和“b”之间的所有质数,并将它们输出到一个名为“Prime1”的文本框中。
- 同时在另一个任务中,找出“c”和“d”之间的所有质数,并将它们输出到一个名为“Prime2”的文本框中。
- 窗口中的一个按钮将允许用户单击它,它会跟踪它被单击的次数,而其他两个任务会查找素数,以演示异步操作。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPF_Asynch_Project
{
public partial class MainWindow : Window
{
public int ClickAmount = 0;
public MainWindow()
{
InitializeComponent();
DelegationIsAwesome();
}
private void Test_Click(object sender, RoutedEventArgs e)
{
ClickAmount++;
MessageBox.Show("You clicked me " + ClickAmount.ToString() + " times!");
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
}
private async void DelegationIsAwesome()
{
Task enumtask = new Task(() => FindPrimes(100000, 100000000));
Task[] enumall = new Task[2];
enumall[0] = enumtask;
enumall[1] = new Task(() => FindPrimes2(1000, 10000));
enumall.ToList().ForEach(t => t.Start());
await Task.WhenAll(enumall).ConfigureAwait(false);
}
private void FindPrimes(long lower, long upper)
{
for (long i = lower; i < upper; i++)
{
long primeornot = 1;
for (long q = 2; q < i; q++)
{
if (i % q == 0)
{
primeornot = 0;
}
}
if (primeornot == 1)
{
System.Threading.Thread.Sleep(6);
Prime1.Dispatcher.BeginInvoke(
(Action)(()=>{ Prime1.Text += i.ToString() + ", "; }));
}
}
}
private void FindPrimes2(int lower, long upper)
{
for (int i = lower; i < upper; i++)
{
int primeornot = 1;
for (int q = 2; q < i; q++)
{
if (i % q == 0)
{
primeornot = 0;
}
}
if (primeornot == 1)
{
System.Threading.Thread.Sleep(5);
Prime2.Dispatcher.BeginInvoke(
(Action)(() => { Prime2.Text += i.ToString() + ", "; }));
}
}
}
}
}
但是我得到了奇怪的结果。以下为节目截图:
显然素数查找方法的输出是不正确的。但为什么它会不断重复同样的数字呢?它有时也会吐出一个等于 UpperBound 的数字,即使 "i" 永远不应等于或大于 UpperBound。
我的输出发生了什么,我该如何解决?
【问题讨论】:
-
顺便说一句,您似乎正在使用值为 0 或 1 的
int变量来表示 false 和 true...为什么不直接使用bool呢?您的代码将更易于阅读。 -
@JonSkeet 我多年前养成的旧坏习惯,令人惊讶的是,没有人叫我出来。一个非常好的建议。
-
您可以考虑将循环“for (int q = 2; q
-
@cscmh99 我昨天确实有那个,但是由于 Jon 指出的 BeginInvoke 的问题,它导致了很多意想不到的行为。但是,现在它已经修复了,我确实使用 Math.Ceiling(Math.Sqrt(i)) 而不仅仅是“i”。
标签: c# wpf multithreading asynchronous async-await