【问题标题】:How can I show a messagebox or loadingbox while doing a loop? (Code may be blocked and after 25 seconds continue)如何在循环时显示消息框或加载框? (代码可能被阻止并在 25 秒后继续)
【发布时间】:2014-12-12 23:41:40
【问题描述】:

我已经有了这个,但它不起作用...我需要检查来自 plc 的位是否高。如果它仍然很高,我需要等待 5 秒并再次检查。现在我正在尝试寻找一些东西,以便为用户提供一些视觉反馈。在文本框中,我想输入“等待...”,而等待后的分数每 5 秒增加一次。我尝试了很多东西,但似乎无法让它发挥作用。大多数情况下它只是挂起 25 秒而不更新 GUI,然后它继续......:/

// First check if the plc bit, that says if there is still an order active, 
// is still set. If so then we wait a couple seconds.
var bitorder = Main.PIOGetValue(jbmis.IO_GET_INPUT, "BoxManInStarted");
int counter = 1;
string loadingpoints = "";

loadtimer.Tick += timer_Tick;
loadtimer.Interval = (int)TimeSpan.FromSeconds(5).TotalMilliseconds;
loadtimer.Start();
loadtimer.Enabled = true;

// Stopwatch sw = new Stopwatch();

while(bitorder != 0 && loadtimercounter != 25)
{
    // TODO multithreaded

    #region testcode
    // MessageBox.Show("Waiting for previous order to be stopped" + loadingpoints);
    // Context.UserMessageService
    //     .ShowMessage("Waiting for previous order to be stopped" + 
    //                  loadingpoints, "Waitingfororder");
    // sw.Start();

    // while (sw.Elapsed < TimeSpan.FromSeconds(25)) 
    // {
    //     if (sw.Elapsed.Seconds % 5 == 0)
    //     {
    //         loadingpoints = loadingpoints + ".";
    //         tbScannedEANPick.Background = Brushes.OrangeRed;
    //         tbScannedEANPick.Text = "Waiting" + loadingpoints;
    //     }                                        
    // }

    // sw.Stop();
    // loadingpoints = loadingpoints + ".";
    // tbScannedEANPick.Background = Brushes.OrangeRed;
    // tbScannedEANPick.Text = "Waiting" + loadingpoints;
    // tbScannedEANPick.UpdateLayout();
    #endregion

    if (loadtimercounter % 5 == 0)
    {
        loadingpoints = loadingpoints + ".";
        tbScannedEANPick.Background = Brushes.OrangeRed;
        tbScannedEANPick.Text = "Waiting" + loadingpoints;
        tbScannedEANPick.IsReadOnly = true;

        bitorder = Main.PIOGetValue(jbmis.IO_GET_INPUT, "BoxManInStarted");
    }

    counter ++;
}

//  After 25 seconds stop timer and continue
loadtimer.Stop();

void timer_Tick(object sender, EventArgs e)
{
    loadtimercounter += 5;
}

我找了半天……我试过用Thread.sleep、定时器、秒表……都在主线程或侧线程中……

提前致谢!!

【问题讨论】:

  • TimerThread.SleepStopWatch 是吗?)只要您在 UI 线程本身中执行 长时间运行的作业,就不会工作。您可以尝试拆分作业并将小部分作业放入计时器(switch/case 步骤)。或者,您可以使用TaskThreadBackgroundWorker 在 UI 线程中简单地完成这项长期工作。

标签: c# timer sleep box


【解决方案1】:

您需要在单独的线程上完成这项工作。查看asynchronous programming

或者你可以简单地使用多线程。我建议使用异步编程来完成后台工作和更新 GUI 的文本框控件。

【讨论】:

  • 是的,我现在正在尝试..但问题是我的主线程仍在继续..它需要暂停 25 秒然后继续。因为 25 秒后我检查该位是否仍然高。
  • 所以你需要暂停主线程而不阻塞GUI?这是你需要的吗?
  • 是的...我现在在主线程中执行循环以检查 myThread.IsAlive 是否为真。如果它为假,那么我可以继续。但现在是一个新问题。我得到一个例外,说有另一个线程拥有的对象(我认为是文本框)...:/我可以使用某种没有“确定”按钮的消息框来显示程序正忙吗?跨度>
  • 我认为显示更多代码比仅显示这部分更有帮助。
  • 我不能把我所有的代码都放在这里.. :(你知道一种方法可以让主线程暂停 25 秒,间隔 5 秒,而 UI 可以被阻止,但我需要显示每 5 秒等待一个盒子?
【解决方案2】:

您应该使用后台工作人员。 有一个专用的报告进度事件,可用于更新您需要的加载框。

Background Worker Class and example

【讨论】:

  • 但是在一个循环中检查一些东西的同时,仅仅想象一个等待 25 秒的小盒子似乎太过分了..
  • 这就是要走的路,如果您想在执行其他操作时更新 UI,则没有其他方法。而且这还不错,试一试你就会发现,一旦你理解它就很容易了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多