【发布时间】:2021-05-01 17:44:38
【问题描述】:
我有以下场景:
我有一个运行自动化脚本的插件类(不幸的是,它是同步的,这是我无法控制的)。启动时,会启动一个任务,该任务在后台连续运行,直到用户停止它。在此任务运行时,它正在解析来自串行端口的流式传入数据并不断更新响应列表。同时,脚本将更改一些其他值并监控响应的反应。
我的问题是 - 解析器可能会抛出异常并导致任何剩余脚本无效。但是,如果这个并行任务抛出,我找不到中断脚本的好方法(即下面的 void Main())。如果我等到我的脚本完成,然后等待任务,我会得到异常,但到那时可能会浪费很多时间。因此,我正在寻找更好的方法来在并行任务错误时中断正在运行的脚本。我尝试在初始同步上下文上发布,但也没有运气。我已经在下面编写了一个示例来模拟类似的场景
public class Test : TestPlugin
{
Task _t;
List<string> data = new List();
public Test(){ }
public override void Cleanup()
{
//_t.Wait();
}
public override void Main()
{
// i want this to be interrupted if the polling task started in startup throws.
//Right here simulates running test steps,
//any of which can access the data that's been updated by the "background" task at any time
try
{
int i = 0;
while (i < 10)
{
Task.Delay(1000).Wait();
Console.WriteLine("step" + i + "Latest: " + data.latest());
i++;
}
}
catch(Exception ex)
{
Console.WriteLine("EXCEPTION");
}
}
public override void Setup()
{
_t = Task.Run(async () =>
{
int i =0;
while (i < 10)
{
await Task.Delay(200);
Console.WriteLine(i);
i++;
//i would parse incoming data and add to array here
data.add(i);
if (i > 3) throw new Exception("UH OH");
}
});
}
}
【问题讨论】:
-
是否要在主任务发生异常时终止子任务?类似的东西?
-
相反,如果子任务 '_t' 抛出,我想终止 main。如果我的解析器爆炸了,那么传入的数据有问题,导致 Main() 方法的结果无效。
-
更改代码以执行所需操作的最简单方法是让主循环在每次迭代时检查Task.IsFaulted。但是,子任务允许异常从任务中冒出可能是个坏主意。相反,您应该考虑传入 CancellationTokenSource 以允许子任务在出错时从
catch块向主循环发出信号。 -
在
Main你可以做Task.WaitAny(Task.Delay(1000), _t); -
@PanagiotisKanavos 可能是正确的解决方案。正如上面提到的 charlieface
标签: c# exception task task-parallel-library