C# 在读取输入时进行计算的窗口窗体应用程序
我正在尝试编写一个Windows窗体应用程序,用于计算小于10^20的数字的素因式分解。但当数字大于10^12时,应用程序在给出结果前几秒钟开始冻结。所以我尝试创建一个线程来分别计算答案。代码如下:C# 在读取输入时进行计算的窗口窗体应用程序,c#,multithreading,visual-studio-2017,C#,Multithreading,Visual Studio 2017,我正在尝试编写一个Windows窗体应用程序,用于计算小于10^20的数字的素因式分解。但当数字大于10^12时,应用程序在给出结果前几秒钟开始冻结。所以我尝试创建一个线程来分别计算答案。代码如下: class fact { static long[] res = new long[202]; static long num; public static string output; static void cal
class fact
{
static long[] res = new long[202];
static long num;
public static string output;
static void calcFact(long n)
{
//calculate prime factorization into array res
}
static void call()
{
calcFact(s);
}
public static void execute(string input)
{
s = long.Parse(input);
ThreadStart childref = new ThreadStart(call);
Thread childThread = new Thread(childref);
childThread.Start();
for (int i = 0; i < len; i++) output += res[i].ToString() + " ";
}
}
private void InputBox_TextChanged(object sender, EventArgs e)
{
if (InputBox.Text != "")
{
fact.execute(InputBox.Text);
output.Text = fact.output;
}
}
类事实
{
静态long[]res=新long[202];
静态长数;
公共静态字符串输出;
静态空隙计算(长n)
{
//计算数组res的素因子分解
}
静态void调用()
{
calcFact(s);
}
公共静态void执行(字符串输入)
{
s=long.Parse(输入);
ThreadStart childref=新的ThreadStart(调用);
线程childThread=新线程(childref);
childThread.Start();
对于(int i=0;i
在不创建新线程的情况下,应用程序可以工作,但现在输出总是空的。有人能解释一下这个线程是如何运行的以及如何修复它的吗?这是因为您正在启动该线程,并在尝试显示其结果之后立即启动该线程。您必须等待线程完成,为此,您可以使用
BackgroundWorker
class fact {
/*...*/
static void calcFact(long n, BackgroundWorker worker)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
//do this code in your loop to break and stop the calculation
//calculate prime factorization into array res
}
var backgroundWorker = new System.ComponentModel.BackgroundWorker();
backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(
backgroundWorker_RunWorkerCompleted);
backgroundWorker.WorkerSupportsCancellation = true;
private void backgroundWorker_DoWork(object sender,
DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
// Assign the result of the computation
// to the Result property of the DoWorkEventArgs
// object. This is will be available to the
// RunWorkerCompleted eventhandler.
var result = calcFact((long)e.Argument, worker);
var outputBkw = string.Empty;
for (int i = 0; i < len; i++) outputBkw += res[i].ToString() + " ";
e.Result = outputBkw;
}
private void backgroundWorker_RunWorkerCompleted(
object sender, RunWorkerCompletedEventArgs e)
{
// First, handle the case where an exception was thrown.
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
else if (e.Cancelled)
{
// Next, handle the case where the user canceled
// the operation.
resultLabel.Text = "Canceled"; // or any other method you are showing status...
}
else
{
// Finally, handle the case where the operation
// succeeded.
resultLabel.Text = e.Result.ToString();
//Here you can use the result with the numbers calculated.
// At this point you can have an event in the calc class to signal that the work is finished.
}
}
private void cancelAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker.WorkerSupportsCancellation == true)
{
// Cancel the asynchronous operation.
backgroundWorker.CancelAsync();
}
}
类事实{
/*...*/
静态无效计算(长n,后台工作人员)
{
if(worker.CancellationPending==true)
{
e、 取消=真;
打破
}
//在循环中执行此代码可以中断并停止计算
//计算数组res的素因子分解
}
var backgroundWorker=new System.ComponentModel.backgroundWorker();
backgroundWorker.DoWork+=新的DoworkerVenthandler(backgroundWorker_DoWork);
backgroundWorker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(
后台工作人员(运行工作已完成);
backgroundWorker.WorkerSupportsScanCellation=true;
私有void backgroundWorker_DoWork(对象发送方,
道夫特(e)
{
BackgroundWorker worker=发件人作为BackgroundWorker;
//分配计算结果
//到DoWorkEventArgs的结果属性
//对象。这将可用于
//RunWorkerCompleted eventhandler。
var result=calcFact((长)e.参数,worker);
var outputBkw=string.Empty;
对于(int i=0;i
更新
要启用取消,您必须在声明后台工作人员时使用
backgroundWorker.WorkerSupportsCancellation=true;
。我已经更新了代码示例以考虑这一点。阅读backgroundWorker
,尤其是RunWorkerCompleted
。您只需处理后台工作人员当数值太大时,计算变得不实际。尝试停止并重新启动线程会给您带来很多麻烦,这是充满竞争条件的。保持简单,当值足够小时立即计算结果,进行“计算”按钮不可见时可见。用户如何取消操作?