Compact Framework的/线程 - 消息框显示在其他控制选项被选择后, [英] Compact Framework/Threading - MessageBox displays over other controls after option is chosen

查看:217
本文介绍了Compact Framework的/线程 - 消息框显示在其他控制选项被选择后,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作,抓住并安装了一堆更新了一个外部服务器,并且需要一些帮助与线程的应用程序。用户遵循以下流程:

I'm working on an app that grabs and installs a bunch of updates off an an external server, and need some help with threading. The user follows this process:


  • 点击次数按钮

  • 方法检查更新,返回计数。

  • 如果大于0,则询问用户是否要使用MessageBox.Show()。

  • 如果是安装,它贯穿一个循环,并调用BeginInvoke()每次更新的run()方法在后台运行。

  • 我的更新类有用于更新进度条等一些事件

  • Clicks button
  • Method checks for updates, count is returned.
  • If greater than 0, then ask the user if they want to install using MessageBox.Show().
  • If yes, it runs through a loop and call BeginInvoke() on the run() method of each update to run it in the background.
  • My update class has some events that are used to update a progress bar etc.

进度条的更新都很好,但在MessageBox不是从屏幕,因为更新循环开始用户点击是之后完全清除(见下图)。

The progress bar updates are fine, but the MessageBox is not fully cleared from the screen because the update loop starts right after the user clicks yes (see screenshot below).


  • 我应该怎么做才能让这些URL更新循环开始前瞬间消失?

  • 我应该使用线程,而不是的BeginInvoke()?

  • 我应该做一个单独的线程初始更新检查,并从该线程调用MessageBox.Show()?

代码

// Button clicked event handler code...
DialogResult dlgRes = MessageBox.Show(
    string.Format("There are {0} updates available.\n\nInstall these now?", 
    um2.Updates.Count), "Updates Available", 
    MessageBoxButtons.YesNo, 
    MessageBoxIcon.Question, 
    MessageBoxDefaultButton.Button2
);

if (dlgRes == DialogResult.Yes)
{
    ProcessAllUpdates(um2); 
}

// Processes a bunch of items in a loop
private void ProcessAllUpdates(UpdateManager2 um2)
{
    for (int i = 0; i < um2.Updates.Count; i++)
    {
        Update2 update = um2.Updates[i];

        ProcessSingleUpdate(update);

        int percentComplete = Utilities.CalculatePercentCompleted(i, um2.Updates.Count);

        UpdateOverallProgress(percentComplete);
    }
}

// Process a single update with IAsyncResult
private void ProcessSingleUpdate(Update2 update)
{
    update.Action.OnStart += Action_OnStart;
    update.Action.OnProgress += Action_OnProgress;
    update.Action.OnCompletion += Action_OnCompletion;

    //synchronous
    //update.Action.Run();

    // async
    IAsyncResult ar = this.BeginInvoke((MethodInvoker)delegate() { update.Action.Run(); });
}



屏幕截图

移动通过错误BrianLy,

推荐答案

您的用户界面没有更新,因为所有的工作都在用户界面线程发生。
你要调用:

Your UI isn't updating because all the work is happening in the user interface thread. Your call to:

this.BeginInvoke((MethodInvoker)delegate() {update.Action.Run(); })

是说创造了这个线程调用上update.Action.Run() (表单),这是用户界面线程。

is saying invoke update.Action.Run() on the thread that created "this" (your form), which is the user interface thread.

Application.DoEvents()

的确给UI线程重绘屏幕的机会,但我很想创建新的委托,并调用BeginInvoke上。

will indeed give the UI thread the chance to redraw the screen, but I'd be tempted to create new delegate, and call BeginInvoke on that.

这将执行从线程池分配一个单独的线程update.Action.Run()函数。然后,您可以随时查看的IAsyncResult直到更新完成后,查询更新对象每次检查后,其进展情况(因为你不能有其他线程更新进度条/ UI),然后调用Application.DoEvents()。

This will execute the update.Action.Run() function on a seperate thread allocated from the thread pool. You can then keep checking the IAsyncResult until the update is complete, querying the update object for its progress after every check (because you can't have the other thread update the progress bar/UI), then calling Application.DoEvents().

您也都应该调用EndInvoke()之后,否则你可能会泄漏资源

You also are supposed to call EndInvoke() afterwards otherwise you may end up leaking resources

我也要受到诱惑,把取消进度对话框按钮,然后添加一个超时,否则如果更新卡(或时间太长),那么你的申请将已经永远锁定。

I would also be tempted to put a cancel button on the progress dialog, and add a timeout, otherwise if the update gets stuck (or takes too long) then your application will have locked up forever.

这篇关于Compact Framework的/线程 - 消息框显示在其他控制选项被选择后,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆