我有一个控制台应用程序,我正在使用TPL,当我点击任务时,它会退出..我是线程新手,有人可以指导我正确的方向(我已经单独执行RunJob,它没有例外)。 。所以我不确定如何从这里调试。
以下是代码:
// Program.cs
static void Main(string[] args)
{
TaskHelper helper = new TaskHelper();
helper.StartProcessing();
}
// TaskHelper Class
public async void StartProcessing()
{
var tasks = new List<Task<bool>>();
int taskNum = _queueList.Count < maxThreads ? _queueList.Count : maxThreads;
for (int i = 0; i < taskNum; i++)
{
UCMDo doObj;
if (_taskQueue.TryDequeue(out doObj))
{
tasks.Add(RunOps(doObj));
}
}
while (tasks.Count > 0)
{
try
{
// Program exits here when its hitting WhenAny line
var t = await Task.WhenAny(tasks);
tasks.Remove(t);
await t;
}
catch (OperationCanceledException)
{
}
catch (Exception exc) { }
finally
{
// add to tasks, and RunOps
}
}
}
async Task<bool> RunOps(UCMDo doJ)
{
var result = await Task.Run(() => UCMFactory.RunJob(_job, doJ));
return result;
}
答案 0 :(得分:4)
如果您在没有等待的情况下致电StartProcessing
,那么会发生什么情况(您不能async void
),因此程序到达Main
的结尾StartProcessing
中的操作仍在运行时结束。
StartProcessing
应该返回一个任务,您应该等待该任务完成。这通常是通过等待任务来完成的(即await helper.StartProcessing()
),但由于您无法在await
中使用Main
,因此您应该同步执行此操作(尽管这是唯一的可以接受的地方:
static void Main(string[] args)
{
TaskHelper helper = new TaskHelper();
helper.StartProcessingAsync().Wait();
}
正如Servy正确指出的那样,一个更强大且生产就绪的解决方案将使用某种消息循环。一个例子是Stephen Cleary's AsyncContext
:
static void Main(string[] args)
{
TaskHelper helper = new TaskHelper();
AsyncContext.Run(() => helper.StartProcessingAsync());
}
注意:
async void
async
方法通常应命名为XAsync
(即StartProcessingAsync
)