c# - 组合 await 与 ContinueWith
问题描述
我遇到了以下我试图理解的异步代码(为本示例进行了简化):
class Program
{
static async Task Main(string[] args)
{
var foo = new Foo();
try
{
var bar = new Bar();
await foo.ComputeNumber(bar.GetNumberAsync());
}
catch (Exception e)
{
Console.WriteLine($"Logged exception: {e}");
}
Console.WriteLine($"The number is {foo.Number}");
Console.ReadKey();
}
}
public class Foo
{
public int Number { get; private set; } = 0;
public async Task ComputeNumber(Task<int> inputTask)
{
await inputTask.ContinueWith(x => Number = x.Result);
}
}
public class Bar
{
public async Task<int> GetNumberAsync()
{
return await Task.Factory.StartNew(() =>
{
if (DateTime.Now.Date.DayOfWeek != DayOfWeek.Monday)
{
throw new Exception("This function works only on Mondays.");
}
return 17;
});
}
}
这段代码按我的预期工作(至少我希望如此),但我认为这个问题应该通过以下方式之一解决(我认为两者都是正确的)。类将Bar
保持不变。
第一种(异步/等待)方法:
class Program
{
static async Task Main(string[] args)
{
var foo = new Foo();
try
{
var bar = new Bar();
await foo.ComputeNumber(bar.GetNumberAsync());
}
catch (Exception e)
{
Console.WriteLine($"Logged exception: {e}");
}
Console.WriteLine($"The number is {foo.Number}");
Console.ReadKey();
}
}
public class Foo
{
public int Number { get; private set; } = 0;
public async Task ComputeNumber(Task<int> inputTask)
{
Number = await inputTask;
}
}
第二种(基于任务的)方法:
class Program
{
static void Main(string[] args)
{
var foo = new Foo();
var bar = new Bar();
foo.ComputeNumber(bar.GetNumberAsync());
Console.WriteLine($"The number is {foo.Number}");
Console.ReadKey();
}
}
public class Foo
{
public int Number { get; private set; } = 0;
public void ComputeNumber(Task<int> inputTask)
{
inputTask.ContinueWith(x =>
{
if (x.IsFaulted)
{
Console.WriteLine($"Logged exception: {x.Exception}");
}
else
{
Number = x.Result;
}
});
}
}
我很欣赏为什么使用异步代码的原始示例可以这样编写的每一个解释。
解决方案
您可以将其await
视为替代大多数用途的语言功能,ContinueWith
因此将两者混合似乎没有必要。
请注意,您的第二次重写与第一次不同,在两个方面。
它吞下错误而不是浮出水面。
它不返回 a
Task
,因此调用者将不知道何时将aNumber
设置为最终结果。
ComputeNumber
目的可疑(这可能是因为它被简化以在此处发布)。为什么不简单地await bar.GetNumberAsync()
然后在后续语句中使用获得的值?的重点await
是允许Task<T>
被视为与T
程序代码中的相同。
推荐阅读
- ionic4 - 在 ionic4 项目的谷歌地图中添加多个位置标记
- sql-server - 触发器创建中的语法不正确
- java - 布尔值不会从真返回假
- java - 如何从 Java 中的 JSON 对象中删除所有 JSON 格式(不仅仅是空格)?
- c# - 为长时间运行的控制台应用程序调用 Console.WriteLine() 会导致内存问题吗?
- python - Python MySQL 注入失败
- javascript - 如何更改innerHTML上的字体大小
- roku - 如何使用 Brightscript 和 Roku 在一个屏幕中混合海报网格/行列表类型?
- java - 如何为不同的 API 版本配置 Swagger 响应?
- angular - 如何从模板驱动的角度形式访问默认值