【发布时间】:2019-03-17 05:22:45
【问题描述】:
问题是我尝试多次运行 RunPrivateMethod(),但遇到阻塞问题,或者在使用 async/await 时直接无法正常工作。而不是在这里分享每一次尝试,我只是把我当前的版本。
在 RunPrivateMethod() 中,exeProcess.WaitForExit() 方法是一个外部程序,基本上是读取/写入/处理/输出数据。我尝试将此作为异步任务运行,但它不起作用。
我不知道这是否合理,但我想限制一次启动的任务数量,所以我在每个案例块的末尾放入了 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();
}
}
}
我为此工作了无数小时并阅读了 Cleary 的书,最新版本是这篇文章的一个版本:Aync/Await action within Task.Run() 目前的结果是,尽管 exeProcess 的启动时间正确,但每组中的最后一个任务仍然有效。我无法在键盘运行时使用它。
我显然为 RunSomeTasks() 尝试了一个直接的异步方法,然后首先等待 RunAsyncMethod。我真的可以使用一些帮助,是的,我已经知道我不知道我在做什么,尽管我花了很长时间阅读和试错。
【问题讨论】:
-
当你在
RunSomeTasks时,此时会阻塞Task.WaitAll(); -
我明白了,但线程将被阻止。 1) 这是什么类型的应用程序(控制台、winform 等)? 2)问题是什么? 3)你想做什么,实现什么?
-
使
RunSomeTasks异步,并使调用此方法的事件处理程序也为async。这样主线程 (UI) 就会对用户点击等做出反应。 -
您不能等待 exeProcess.WaitForExit。但是您可以使用 TaskCompletionSource 结合Process.Exited 事件
-
听起来你的任务是 IO 绑定的。 不要将 IO 绑定任务移到工作线程上。将它们保留在 UI 线程上并使用异步 IO。否则你正在做的是雇佣工人,然后付钱让他们睡觉!
标签: c# asynchronous async-await task-parallel-library