我想制作一个基于线程的素数计算器。
问题是UI冻结而且没有数字发生。
代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Threading;
namespace PrimeNumbers
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//private delegate void AddListItem(int item);
Thread t;
bool interrupt;
public MainWindow()
{
InitializeComponent();
}
private void btss_Click(object sender, RoutedEventArgs e)
{
if (t == null)
{
t = new Thread(this.calculate);
t.Start();
btss.Content = "Stop";
}
else
{
t.Interrupt();
}
}
private void calculate()
{
int currval = 2;
while (!interrupt)
{
for (int i = 2; i < currval/2; i++)
{
if (2 % i != 0)
{
AddListBoxItem(currval);
}
}
currval++;
}
}
private void AddListBoxItem(int item)
{
if (this.lbPrimes.Dispatcher.Thread == Thread.CurrentThread)
{
lbPrimes.Items.Add(item.ToString());
}
else
{
lbPrimes.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
new Action(
delegate()
{
lbPrimes.Items.Add(item.ToString());
}
));
}
}
}
}
答案 0 :(得分:0)
删除开始你需要调用它我的意思是
“lbPrimes.Dispatcher.Invoke(..”instaed of“lbPrimes.Dispatcher.BeginInvoke(...”
这显示了数字,但是如果你想要一个正确的解决方案,你需要类似下面的代码。
/// <summary>
/// /// Interaction logic for MainWindow.xaml
/// /// </summary>
public partial class MainWindow : Window
{
//private delegate void AddListItem(int item);
Thread t;
private long num = 3;
private bool interrupt = true;
private bool NotAPrime = false;
public MainWindow()
{
InitializeComponent();
}
private void AddListBoxItem(int item)
{
lbPrimes.Dispatcher.BeginInvoke
(DispatcherPriority.Send,
new Action(delegate()
{
lbPrimes.Items.Add(item.ToString());
}));
}
private void btss_Click(object sender, RoutedEventArgs e)
{
if (!interrupt)
{
interrupt = true;
btss.Content = "Resume";
}
else
{
interrupt = false;
btss.Content = "Stop";
btss.Dispatcher.BeginInvoke(
DispatcherPriority.Normal,
new Action(calculate));
}
}
public void calculate()
{
NotAPrime = false;
for (long i = 3; i <= Math.Sqrt(num); i++)
{
if (num % i == 0)
{
NotAPrime = true;
break;
}
}
if (!NotAPrime)
{
lbPrimes.Items.Add(num.ToString());
}
num += 2;
if (!interrupt)
{
btss.Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.SystemIdle,
new Action(this.calculate));
}
}
}