gpt4 book ai didi

c# - 关于任务延续的问题

转载 作者:太空宇宙 更新时间:2023-11-03 14:12:52 24 4
gpt4 key购买 nike

任务 1:

public Task SendMail(string email)
{
...
}

任务 2:

public Task<int> SaveToDB(User user)
{
...
}

我需要做的:

  1. 当task1失败时,返回“发送失败”信息;
  2. 当任务 1 成功时,任务 2 开始。
  3. 当 task2 失败时,应返回“保存失败”信息。
  4. 当task2成功时,应该返回一个“保存成功”的信息。

请帮我想个办法:

public Task<string> SendAndSave(User user){
var task1 = SendMail(user.Email);
var task1Failed = task1.ContinueWith(t =>
{
var e = task1.Exception;
return "Send Failed";
},
TaskContinuationOptions.OnlyOnFaulted |
TaskContinuationOptions.ExecuteSynchronously);

var task2 = task1.ContinueWith(t =>
{
var save = SaveToDB(user);
try
{
int result = save.Result;
return "Save Succeeded";
}
catch(AggregateException ae)
{
return "Save Failed";
}
},
TaskContinuationOptions.NotOnFaulted);

return Task.Factory.ContinueWhenAny(new[] {task1Failed, task2}, t => t.Result);
}

当我运行它时,我收到一个错误。

我将其调用为:

var result = SendAndSave(user).Result;

错误发生在:

public Task<string> SendAndSave(User user)
{
...
return Task.Factory.ContinueWhenAny(new[] {task1Failed, task2}, t => t.Result); //Here: A task was cancelled
}

调试后,有两个问题:

  • Q1:task1、task1Failed、task2创建后,各自的值CreationOption 属性为“无”,尽管其状态为“等待激活”。似乎所有的延续选项都是无效。

  • Q2:对于Task.Factory.ContinueWhenAny(new[] {task1Failed,task2}, t => t.Result), 我们将其命名为“factoryTask”,ContinueWhenAny 似乎无效。在内部放置断点后task1Failed、task2 和 factoryTask 中的每一个,我偶尔会看到factoryTask 中的断点首先被击中,尽管它应在 task1Failed 或 task2 完成后触发。

有人可以帮忙吗?谢谢。

最佳答案

虽然我不完全理解你的问题,但我理解这里的问题,基本上你总是有 task1Failed 或 task2 完成,但不会同时完成,另一个将被取消!所以在 WaitOnAny 调用中,如果它发现其中一个任务已经被取消,它就会崩溃,这实际上取决于任务参数的顺序,所以在上面的例子中你首先传递 task1failed,所以如果这个任务完成 ContinueWhenAny 将工作很好,因为它检查的第一个任务已经完成,所以它不会检查另一个任务,但是如果 task1Failed 没有运行所以它处于取消状态,ContinueWhenAny 将抛出!

为避免这种情况,您需要改用 TaskCompletetionSource,运行的任务将设置该值,然后在最后返回 tcs.Task.Result

public Task<string> SendAndSave(User user){
var tcs = new TaskCompletionSource<string>();
var task1 = SendMail(user.Email);
var task1Failed = task1.ContinueWith(t =>
{
var e = task1.Exception;
tcs.TrySetResult("Send Failed");
},
TaskContinuationOptions.OnlyOnFaulted |
TaskContinuationOptions.ExecuteSynchronously);

var task2 = task1.ContinueWith(t =>
{
var save = SaveToDB(user);
try
{
int result = save.Result;
tcs.TrySetResult("Save Succeeded");
}
catch(AggregateException ae)
{
tcs.TrySetResult("Save Failed");
}
},TaskContinuationOptions.NotOnFaulted);

return tcs.Task.Result;
}

关于c# - 关于任务延续的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7252516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com