首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#.net,在处理长任务时引发事件,显示一个窗体,该窗体可以有"Pause“和" continue”以继续处理

C#.net,在处理长任务时引发事件,显示一个窗体,该窗体可以有"Pause“和" continue”以继续处理
EN

Stack Overflow用户
提问于 2018-02-14 08:24:00
回答 2查看 208关注 0票数 0

我逐行处理文件,读取具有时间戳和相关数据的各种事件。我想要能够显示一个表单,同时进行处理,我需要与之交互和截取一些事件,有一个按钮说中断EventX,如果它被按下,它将显示一个丰富的文本框字段中的事件数据,当这个事件在未来的某个时候到达。然后,我可以更改一些事件数据(假设我模拟了一些条件),当我按下" resume“时,它应该通过向目标订阅者引发一个事件以进行进一步处理来恢复处理。

因此,我需要一个拦截器,当某个表单元素被按下并将数据传递给目标订阅者时,它将通过传递机制。我可以同步等待修改数据并按"Resume“

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-14 08:30:40

如果您希望在执行长时间运行的操作时具有响应式GUI,则需要某种形式的多任务处理。这意味着异步/等待或许多多线程(主要是线程和BackgroundWorker )方法中的任何一种

虽然可以添加暂停和恢复,但这样做通常比值得做的工作更多。至少,你会遇到一些问题,比如仍然保留的文件句柄或竞争条件。通常,“取消”操作比完全停止/继续操作要好得多。

作为一个初学者,我建议你使用BackgroundWorker。这几乎是通过多线程进入多任务处理的最简单方法。几年前,我甚至为它写了一个例子:

代码语言:javascript
复制
#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
    if (!bgwPrim.IsBusy)
    {
        //Prepare ProgressBar and Textbox
        int temp = (int)nudPrim.Value;
        pgbPrim.Maximum = temp;
        tbPrim.Text = "";

        //Start processing
        bgwPrim.RunWorkerAsync(temp);
    }
}

private void btnPrimCancel_Click(object sender, EventArgs e)
{
    if (bgwPrim.IsBusy)
    {
        bgwPrim.CancelAsync();
    }
}

private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
    int highestToCheck = (int)e.Argument;
    //Get a reference to the BackgroundWorker running this code
    //for Progress Updates and Cancelation checking
    BackgroundWorker thisWorker = (BackgroundWorker)sender;

    //Create the list that stores the results and is returned by DoWork
    List<int> Primes = new List<int>();


    //Check all uneven numbers between 1 and whatever the user choose as upper limit
    for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
    {
        //Report progress
        thisWorker.ReportProgress(PrimeCandidate);
        bool isNoPrime = false;

        //Check if the Cancelation was requested during the last loop
        if (thisWorker.CancellationPending)
        {
            //Tell the Backgroundworker you are canceling and exit the for-loop
            e.Cancel = true;
            break;
        }

        //Determin if this is a Prime Number
        for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
        {
            if (PrimeCandidate % j == 0)
                isNoPrime = true;
        }

        if (!isNoPrime)
            Primes.Add(PrimeCandidate);
    }

    //Tell the progress bar you are finished
    thisWorker.ReportProgress(highestToCheck);

    //Save Return Value
    e.Result = Primes.ToArray();
}

private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    pgbPrim.Value = e.ProgressPercentage;
}

private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    pgbPrim.Value = pgbPrim.Maximum;
    this.Refresh();

    if (!e.Cancelled && e.Error == null)
    {
        //Show the Result
        int[] Primes = (int[])e.Result;

        StringBuilder sbOutput = new StringBuilder();

        foreach (int Prim in Primes)
        {
            sbOutput.Append(Prim.ToString() + Environment.NewLine);
        }

        tbPrim.Text = sbOutput.ToString();
    }
    else 
    {
        tbPrim.Text = "Operation canceled by user or Exception";
    }
}
#endregion
票数 2
EN

Stack Overflow用户

发布于 2018-02-18 08:18:08

谢谢你,克里斯托弗

我接受了你的回答,因为你给了我一些如何解决我的问题的建议。你可以看到下面我是如何解决这个问题的。

Rad

代码语言:javascript
复制
//class variable
private SimulatorRunner simulatorRunner;

//Code behind DevicesSimulatorForm form
private void RunSimulator()
{
	btnRerun.BackColor = Color.BurlyWood;
	ParameterizedThreadStart start = new ParameterizedThreadStart(RunSimulator);
	Thread simulatorProcessingThread = new Thread(start);
	simulatorProcessingThread.Start(this);
}

//This will run in a separate thread so when accessing controls Invoke is being used.
public void RunSimulator(object form)
{
	DevicesSimulatorForm devicesSimulatorForm = (DevicesSimulatorForm) form;
	simulatorRunner.Run(devicesSimulatorForm);
        devicesSimulatorForm.InvokeEx(formInner =>
	{
		formInner.btnRerun.BackColor = Color.LightGray;
		InitializeFields();
		InitializeTextBackBorder();
		InitializeButtonControls();
		running = false;
	});

}


public class SimulatorRunner
{
   public void Run(DevicesSimulator form)
    { 
    
      string buffer = "Some content read from file in a loop that needs to be passed 
                      to a rich text box when a boolean Intercept check box is true
                      and FormStatusIntercept will return true and with Thread.Sleep(1)
                      we will have a chance to update the buffer to the new value and by
                      unchecking Intercept check box we will exit while loop and continue
                      processing"      
      while (true)
      {
        if (FormStatusIntercept(form, ref buffer))
        {
          Thread.Sleep(1);
        }
        else
        {
          publishEventArgs.Buffer = buffer;
          break;
        }
      }

      PublishEvent?.Invoke(this, publishEventArgs);
   }
}

private bool FormStatusIntercept(DevicesSimulator simulatorForm, ref string buffer)
{
	string modifiedBuffer = buffer;
  //When btnFormStatus button is pressed it changes FormStatusContinued = true
  //which allows continuation of the processing by exiting while loop
	if (simulatorForm.FormStatusContinued == true)
	{
		simulatorForm.InvokeEx(form =>
		{
			if (form.rtbFormStatus.Text != modifiedBuffer)
			{
				modifiedBuffer = form.rtbFormStatus.Text;
			}
			form.FormStatusContinued = false;
			form.FormStatusInterceptPending = false;
		});
		buffer = modifiedBuffer;
		return false;
	}
	else if (simulatorForm.FormStatusIntercept == true)
	{
		if (simulatorForm.FormStatusInterceptPending == false)
		{
      //Whith check box pressed (true) we request a stop
      //and we enter a while loop with Thread.Sleep(1)
			simulatorForm.InvokeEx(form =>
			{
				form.btnFormStatus.Text = "Continue";
				form.rtbFormStatus.Text = modifiedBuffer;
				form.FormStatusInterceptPending = true;
			});
		}
		return true;
	}
	return false;
}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48777842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档