【问题标题】:Parallel - threads? loops?并行 - 线程?循环?
【发布时间】:2013-05-03 05:06:20
【问题描述】:

所以我有一个使用 Google 地球的应用程序。我单击一个按钮,然后弹出一个新表单。当用户在主表单中单击 Google 地球上的地点时,此表单保持打开状态。弹出此表单后,将运行一个循环,等待用户单击“确定”或“取消”。目前,当弹出窗口存在时,我无法与主 Google 地球表单进行任何用户交互。

我什至不确定处理它的最佳方法,因此很难搜索相关内容。

这是我迄今为止尝试过的:

这是按下按钮后代码的第一部分,以下所有内容都通用:

            Form TotArea = new ASPE.GUI.OptimizationWizard.TotalArea();
            DialogResult dr1 = new DialogResult();
            Thread t = new Thread(() => dr1 = TotArea.ShowDialog());
            t.Start();
            //TotArea.TopMost = true;
            bool firstcall = true;
            dynamic[] polystuff = null;

在对话框弹出后运行一个while循环(我知道这会失败):

        while (dr1 != DialogResult.OK & dr1 != DialogResult.Cancel)
        {
            //do stuff
        } 

使用“Parallel.For”:

        Parallel.For(0, 1, i =>
        {
         //do stuff
        });

这失败了,因为我不知道如何让它等待我点击对话框。

使用这个“Parallel While”http://blogs.msdn.com/b/pfxteam/archive/2009/08/12/9867246.aspx: ParallelOptions 并行选项 = 新的 ParallelOptions();

        Func<bool> condn = () => (dr1 != DialogResult.OK | dr1 != DialogResult.Cancel);
        Action whilebody = () =>
        {
             //do stuff    
        };

还有这些功能:

        While(paralleloptions, condn, whilebody);  
    private static IEnumerable<bool> IterateUntilFalse(Func<bool> condition)
    {
        while (condition()) yield return true;
    }
    public static void While(
ParallelOptions parallelOptions, Func<bool> condition, Action body)
    {
        Parallel.ForEach(IterateUntilFalse(condition), parallelOptions,
            ignored => body());
    }

这对我来说完全陌生,它似乎运行得如此之快以至于它根本不是真正的并行。

有人可以在这里提出任何建议吗?

谢谢。

【问题讨论】:

  • 你为什么要运行一个繁忙的循环?一旦你调用ShowDialog,你将暂停该线程的执行,直到ShowDialog返回(即关闭你的第二个表单。如果你希望表单都可见和交互,只需调用Show

标签: c# task-parallel-library


【解决方案1】:

ShowDialog 应该暂停执行,直到返回对话结果。因为您在单独的线程中显示对话框,所以它不会停止您当前的对话框。

您可以返回使用 Parallel.For 并将您的代码更改为:

if (DialogResult.OK == TotArea.ShowDialog())
{
     Parallel.For(0, 1, i =>
     {
          //do stuff
     });
}

如果必须在后台执行,也可以使用 Task.Factory:

var task = Task.Factory.StartNew(() => { return TotArea.ShowDialog(); });
task.Wait();
if (task.Result == DialogResult.OK)
{
     Parallel.For(0, 1, i =>
     {
          //do stuff
     });
}

【讨论】:

  • 我对 Parallel for 的一个问题是我不知道如何控制表单输入运行的时间。我相信如果我实施您的建议,TotArea 表单将不对循环运行的迭代长度负责?
  • 而且似乎这个建议在运行循环之前等待用户输入。我需要循环运行,直到用户单击确定或取消。
猜你喜欢
  • 1970-01-01
  • 2015-02-05
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-27
  • 2021-10-26
相关资源
最近更新 更多