gpt4 book ai didi

c# - CS1998如何实现不警告的同步任务返回方法?

转载 作者:行者123 更新时间:2023-12-02 00:14:09 24 4
gpt4 key购买 nike

以下界面为例:

interface IOracle
{
Task<string> GetAnswerAsync(string question);
}

此接口(interface)的某些实现可能会使用async/await。其他人可能不需要。例如,考虑这个简单的玩具实现。

class SimpleOracle
{
public Dictionary<string, string> Lookup { get; set; }

// Warning CS1998: This async method lacks 'await' operators
// and will run synchonously.
public async Task<string> GetAnswerAsync(string question)
{
string answer = Lookup[question];
return answer;
}
}

编译器警告 CS1998 当然是有道理的。通常的建议是 remove the async keyword and use Task.FromResult ,但它忽略了一个微妙的问题。如果代码抛出异常怎么办?然后,该代码转换会更改该方法的行为:async 版本会将任何异常包装在 Task 中;如果没有显式的 try-catch,非async 版本不会。

保留 async 关键字完全按照我想要的方式工作,但它会产生编译器警告,而且我认为抑制这些警告并不明智。

我应该如何重构我的方法实现,以便不产生编译器警告,同时像任何其他 async 方法一样使用 Task 包装所有异常?

最佳答案

我用来从 async 转换而来的机械翻译产生编译器警告 CS1998 到非 async 的版本行为相同的版本如下。

  • 删除 async关键字。
  • try 包裹整个现有方法主体-catch .
  • 定义 TaskCompletionSource<T>tcs之前try -catch .
  • 替换 return <expr>; 的所有现有实例与 tcs.SetResult(<expr>);接下来是 return tcs.Task; .
  • 定义 catch阻止调用 tcs.SetException(e)接下来是 return tcs.Task; .

例如:

public Task<string> GetAnswerAsync(string question)
{
var tcs = new TaskCompletionSource<string>();
try
{
string answer = Lookup[question];
tcs.SetResult(answer);
return tcs.Task;
}
catch (Exception e)
{
tcs.SetException(e);
return tcs.Task;
}
}

这可以通过以下方式更普遍地表达,尽管我不知道在代码库中实际引入这样的辅助方法是否合适。

public static Task<T> AsyncPattern(Func<T> func)
{
var tcs = new TaskCompletionSource<T>();
try
{
tcs.SetResult(func());
}
catch (Exception e)
{
tcs.SetException(e);
}
return tcs.Task;
}

关于c# - CS1998如何实现不警告的同步任务返回方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30852463/

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