代码之家  ›  专栏  ›  技术社区  ›  Missy

Task.Run(asnyc()=>)阻止/不运行所有任务C#

  •  1
  • Missy  · 技术社区  · 6 年前

    我不知道这是否合理,但是我想限制一次启动的任务的数量,所以我在每个case块的末尾添加了Task.WaitAll()。案例(1)和案例(2)都将运行。

    我真的非常感谢你在这方面的任何意见或帮助。我的大多数测试最后都锁定了我的系统和键盘。

    public void RunSomeTasks(int group)
        {
    
            switch (group)
            {
    
                case (1):
                    {
                        Task.Run(async () => await RunAsyncMethod(param1, param1, group));
                        Task.Run(async () => await RunAsyncMethod(param1, param2, group));
                        Task.Run(async () => await RunAsyncMethod(param1, param3, group));
                        Task.WaitAll();
                        break;
                    }
                case (2):
                    {
                        Task.Run(async () => await RunAsyncMethod(param2, param1, group));
                        Task.Run(async () => await RunAsyncMethod(param2, param2, group));
                        Task.Run(async () => await RunAsyncMethod(param2, param3, group));
                        Task.WaitAll();
                        break;
                    }
            }
        }
    
        async Task RunAsyncMethod(string var1, string var2, string varGroup)
        {           
    
            ////////////////////////////////////////////
            // Use ProcessStartInfo class
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.CreateNoWindow = false;
            startInfo.UseShellExecute = false;
            startInfo.FileName = "SomeOutsideEXE";
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.Arguments = var1 + " " + var2 + " " + varGroup;
            using (Process exeProcess = Process.Start(startInfo))
            {
                // did not work -> Task.Run(() => exeProcess.WaitForExit()).Wait();
                exeProcess.WaitForExit();
            }
        }
    }
    

    我为此花了无数个小时,读了克利里的书,这本最新的修订版是这篇文章的一个版本: Aync/Await action within Task.Run()

    很明显,我尝试了RunSomeTasks()的直接异步方法,然后等待runasynchmethod。我真的需要一些帮助,是的,我已经知道我不知道我到底在做什么,尽管我花了很长时间阅读和反复尝试。

    1 回复  |  直到 6 年前
        1
  •  4
  •   C. Mitchell    6 年前

    我对你的例子做了一点修改,这样可以防止UI被锁定。注意,我补充道 async

        private async void button1_Click(object sender, EventArgs e)
        {
            try
            {
                await RunSomeTasks(1);
                await RunSomeTasks(2);
                lblStatus.Text = "done!";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    
        public async Task RunSomeTasks(int group)
        {
            switch (group)
            {
                case (1):
                    {
                        var t1 = RunMethodAsync(param1, param1, group);
                        var t2 = RunMethodAsync(param1, param2, group);
                        var t3 = RunMethodAsync(param1, param3, group);
                        await Task.WhenAll(t1, t2, t3).ConfigureAwait(false);
                        break;
                    }
                case (2):
                    {
                        var t1 = RunMethodAsync(param2, param1, group);
                        var t2 = RunMethodAsync(param2, param2, group);
                        var t3 = RunMethodAsync(param2, param3, group);
                        await Task.WhenAll(t1, t2, t3).ConfigureAwait(false);
                        break;
                    }
            }
        }
    
        async Task RunMethodAsync(string var1, string var2, int varGroup)
        {
            ////////////////////////////////////////////
            // Use ProcessStartInfo class
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.CreateNoWindow = false;
            startInfo.UseShellExecute = false;
            startInfo.FileName = "SomeOutsideEXE";
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            startInfo.Arguments = var1 + " " + var2 + " " + varGroup;
    
            using (Process exeProcess = new Process())
            {
                var cts = new TaskCompletionSource<int>();
    
                exeProcess.StartInfo = startInfo;
                exeProcess.EnableRaisingEvents = true;
    
                exeProcess.Exited += (sender, e) =>
                {
                    try
                    {
                        cts.SetResult(exeProcess.ExitCode);
                    }
                    catch (Exception ex)
                    {
                        cts.SetException(ex);
                    }
                };
    
                exeProcess.Start();
    
                await cts.Task.ConfigureAwait(false);
            }
        }
    
        2
  •  2
  •   Tristan Trainer Ferguson Osas    6 年前

    我想出的最干净的方法 await Process.WaitForExit events 等。

    private async Task RunRubyScript(string filePath)
    {
      await Task.Run(() =>
      {
        using (var proc = new Process())
        {
          var startInfo = new ProcessStartInfo(@"ruby");
          startInfo.Arguments = filePath;
          startInfo.UseShellExecute = false;
          startInfo.CreateNoWindow = true;
          proc.StartInfo = startInfo;
          proc.Start();
          proc.WaitForExit();
        }
      });
    }
    

    这是为了运行一个 ruby 脚本,但显然修改你 ProcessStartInfo

    希望这有帮助!