用于 C# 在进程完成之前完成的基于事件的任务框架
Event based Task framework for C# completing before process complete
我正在尝试创建一个系统来处理作为单独任务传入的事件。这一切都在一个 Windows 服务应用程序中,该应用程序一直运行到停止为止,停止时会等到所有任务完成后再停止。
我有以下简化代码:
IList<Task> _tasks = new List<Task>();//this is a private class variable.
private void Event_Fired(object sender, eventArgs e)
{
StartTask();
}
private void StartTask(){
Task task = Task.Factory.StartNew(async () => await process.ProcessEvent(true, StoppingToken));
_tasks.Add(task);
}
private void MonitorTasks(){
for (int i = _tasks.Count - 1; i >= 0; i--)
{
Task aTask = _laneTasks[i];
if (aTask.IsCompleted)
{
_tasks.Remove(aTask);
Log.Information($"Task {aTask.Id} completed.");
}
}
}
public async Task ProcessEvent(){
//do some async processing
await Task.Delay(5000); //if I add a delay before returning the Task, it is completed prior to this delay.
}
我遇到的问题是任务在 ProcessEvent 完成之前 正在完成。我需要确保在允许进程停止之前完成任务。
该进程还必须允许新事件随时进入并产生新任务。
我觉得我在这里缺少一些基本的东西。任何帮助将不胜感激。
这可能是你的问题:
Task task = Task.Factory.StartNew(async () => await process.ProcessEvent(true, StoppingToken));
这会启动一个新任务,该任务会立即完成。请尝试 运行 任务。
Task task = Task.Run(() => process.ProcessEvent(true, StoppingToken));
Task.Factory.StartNew(...)
创建一个新的 Task
来执行提供的委托。 returned Task
的具体类型将取决于委托的 return 类型。
那么让我们看看您传入的委托:
async () => await process.ProcessEvent(true, StoppingToken)
好的,那是 Func<Task>
。调用该函数将创建一个新的 Task
和 return 它。所以你的 Task<Task>
立即完成,Result
值设置为内部 Task
对象。
更复杂的是,ProcessEvent()
本身创建了一个 Task
,最终就是您要等待的内容。所以你正在创建一个 Task
来创建一个 Task
来等待 Task
。当然 outer-most Task
会在服务员 Task
创建后立即完成,因为它的工作现在已经 完成 .
由于您的代码已经在 Task
对象集合中进行手动等待,因此您不需要 Task
其全部目的是等待最里面的 Task
完成.并且由于您已经 return 从 ProcessEvent()
创建 Task
,因此您不需要 Task
来创建 Task
.
改为这样做:
_tasks.Add(ProcessEvent());
我正在尝试创建一个系统来处理作为单独任务传入的事件。这一切都在一个 Windows 服务应用程序中,该应用程序一直运行到停止为止,停止时会等到所有任务完成后再停止。
我有以下简化代码:
IList<Task> _tasks = new List<Task>();//this is a private class variable.
private void Event_Fired(object sender, eventArgs e)
{
StartTask();
}
private void StartTask(){
Task task = Task.Factory.StartNew(async () => await process.ProcessEvent(true, StoppingToken));
_tasks.Add(task);
}
private void MonitorTasks(){
for (int i = _tasks.Count - 1; i >= 0; i--)
{
Task aTask = _laneTasks[i];
if (aTask.IsCompleted)
{
_tasks.Remove(aTask);
Log.Information($"Task {aTask.Id} completed.");
}
}
}
public async Task ProcessEvent(){
//do some async processing
await Task.Delay(5000); //if I add a delay before returning the Task, it is completed prior to this delay.
}
我遇到的问题是任务在 ProcessEvent 完成之前 正在完成。我需要确保在允许进程停止之前完成任务。
该进程还必须允许新事件随时进入并产生新任务。
我觉得我在这里缺少一些基本的东西。任何帮助将不胜感激。
这可能是你的问题:
Task task = Task.Factory.StartNew(async () => await process.ProcessEvent(true, StoppingToken));
这会启动一个新任务,该任务会立即完成。请尝试 运行 任务。
Task task = Task.Run(() => process.ProcessEvent(true, StoppingToken));
Task.Factory.StartNew(...)
创建一个新的 Task
来执行提供的委托。 returned Task
的具体类型将取决于委托的 return 类型。
那么让我们看看您传入的委托:
async () => await process.ProcessEvent(true, StoppingToken)
好的,那是 Func<Task>
。调用该函数将创建一个新的 Task
和 return 它。所以你的 Task<Task>
立即完成,Result
值设置为内部 Task
对象。
更复杂的是,ProcessEvent()
本身创建了一个 Task
,最终就是您要等待的内容。所以你正在创建一个 Task
来创建一个 Task
来等待 Task
。当然 outer-most Task
会在服务员 Task
创建后立即完成,因为它的工作现在已经 完成 .
由于您的代码已经在 Task
对象集合中进行手动等待,因此您不需要 Task
其全部目的是等待最里面的 Task
完成.并且由于您已经 return 从 ProcessEvent()
创建 Task
,因此您不需要 Task
来创建 Task
.
改为这样做:
_tasks.Add(ProcessEvent());