请看下面的代码 -
static void Main(string[] args)
{
// Get the task.
var task = Task.Factory.StartNew<int>(() => { return div(32, 0); });
// For error handling.
task.ContinueWith(t => { Console.WriteLine(t.Exception.Message); },
TaskContinuationOptions.OnlyOnFaulted);
// If it succeeded.
task.ContinueWith(t => { Console.WriteLine(t.Result); },
TaskContinuationOptions.OnlyOnRanToCompletion);
Console.ReadKey();
Console.WriteLine("Hello");
}
private static int div(int x, int y)
{
if (y == 0)
{
throw new ArgumentException("y");
}
return x / y;
}
Run Code Online (Sandbox Code Playgroud)
如果我在发布模式下执行代码,输出为"发生了一个或多个错误",一旦我点击"Enter"键,"Hello"也会显示.如果我在调试模式下运行代码,输出与但是在IDE中调试时,当控件执行该行时,会出现IDE异常消息("用户代码中未处理的异常")
throw new ArgumentException("y");
Run Code Online (Sandbox Code Playgroud)
如果我从那里继续,程序不会崩溃并显示与发布模式相同的输出.这是处理异常的正确方法吗?
由于C#的Task是一个类,你显然无法将其转换Task<TDerived>为a Task<TBase>.
但是,你可以这样做:
public async Task<TBase> Run() {
return await MethodThatReturnsDerivedTask();
}
Run Code Online (Sandbox Code Playgroud)
是否有一个静态任务方法我可以调用来获取一个Task<TDerived>基本上只指向底层任务并转换结果的实例?我喜欢这样的东西:
public Task<TBase> Run() {
return Task.FromDerived(MethodThatReturnsDerivedTask());
}
Run Code Online (Sandbox Code Playgroud)
这种方法存在吗?是否仅为此目的使用异步方法有任何开销?
假设您有一个包装内部长时间运行方法的方法.这种外部方法可以在调用所述长时间运行的方法之前/之后进行少量工作.例如:
public async Task<int> LongRunningWrapperAsync()
{
int result = await LongRunningAsync();
result++;
return result;
}
Run Code Online (Sandbox Code Playgroud)
似乎使用生成的样板代码的附加权重async不一定值得使用await,因为它的继续基本上是微不足道的.因此,给定一个足够微不足道的*延续,使用它是否更高效Task.ContinueWith?例如
public Task<int> LongRunningWrapperAsync()
{
return LongRunningAsync().ContinueWith(task => task.Result + 1,
TaskContinuationOptions.ExecuteSynchronously);
}
Run Code Online (Sandbox Code Playgroud)
*是的,'足够'和'琐碎'都是模糊的术语.此外,我在这个人为的例子中忽略了异常处理.我认为处理异常的必要性意味着延续是非平凡的.