我有一个问题,我有一个使用异步函数的库,GetParametersByPathAsync(在此定义:https://github.com/aws/aws-sdk-net/blob/master/sdk/src/Services/SimpleSystemsManagement/Generated/_mobile/AmazonSimpleSystemsManagementClient.cs#L2718)
我有一个定义为
的库函数Task<Dictionary<string,string>> GetAllParameters(string region)
{
var pars = DoParameterGatheringWork(reigion);
...(do some more work)
return dict;
}
调用另一种方法
async Task<Dictionary<string,string>> DoParameterGatheringWork(string region)
{
...
var response = await GetParametersByPathAsync(requestObj);
... (process the response)
return parameterDict;
}
等待GetParametersByPathAsync
并收集内容。
这是一个问题,因为我的服务必须从静态构造函数调用GetAllParameters
并初始化参数Dictionary<string,string> MyParameters { get; }
我想在库中的某个位置阻止任务冒泡,因此它只能公开Dictionary<string,string> GetAllParameters(string region)
,而不是任务版本。 (我完全没问题就变得同步了。)
我认为我不应该仅仅执行Task.Wait()
或Task.Result
,因为这会导致死锁。
也许这不是最好的方法,但我不确定如何从这里继续。
任何想法都将不胜感激!
编辑:
这是我想要的构造函数代码:
public class MyConfiguration
{
static MyConfiguration()
{
...
Parameters = ServiceConfiguration.GetAllParameters(); // (library call)
}
public static Dictionary<string, string> Parameters { get; }
}
并且客户端只能通过MyConfiguration.Parameters["IAMAPARAMETER"]
答案 0 :(得分:0)
评论后:在这个答案的最后:如何从非异步方法调用异步方法
显然DoParameterGatheringWork
是一个通常需要忙着等待另一个进程的函数,比如数据库,文件或来自互联网的一些信息。
该函数的设计者认为,如果您的线程暂时等待此删除操作的结果,那将是浪费时间。因此,他决定将其设置为异步,因此调用者可以执行其他操作,而另一个进程将处理请求。
您认为这意味着这意味着所有调用者也应该是异步的,并且构造函数不能是异步的。
如果您希望受益于async-await的优势(意味着您的调用者可以继续处理而不是空闲等待,请使您的构造函数更轻,并让一些Create函数执行您通常在构造函数中执行的异步作业。强制每个想要你的类的对象使用这个异步创建函数的人。
public class MyConfiguration
{
// Static async Create function, does everything you'd normally do in the constructor:
public static async Task<MyConfiguration> CreateAsync()
{
Dictionary<string,string> allParameters = await ServiceConfiguration.GetAllParameters(...);
MyConfiguration createdConfiguration = new MyConfiguration(allParameters);
return createdConfiguration;
}
// make sure that no one except CreateAsync can call the constructor:
private MyConfiguration(Dictionary<string,string> allParameters)
{
parameters = allParameters;
}
}
你所做的就是让构造函数尽可能轻量级并完成所有困难的工作,包括在CreateAsync函数中等待。
<强>用法:强>
以下将导致编译器错误,因此您在开始运行之前就知道了该问题:
MyConfiguration config = new MyConfiguration(...);
正确使用:
async Task<...> DoSomethingAsync(...)
{
...
// I need a configuration:
MyConfiguration config = await MyConfiguration.Create();
// from here you can use the fully initialized MyConfiguration object:
config.DoSomethingElse();
...
}
简单的纪念活动
添加:如何从非异步函数调用异步方法
要从非异步方法调用异步函数,请使用Task.Run启动异步函数,Task.Wait等待异步函数完成,Task.Result获取返回异步函数的值。
static void Main(string[] args)
{
// call an async function:
var asyncTask = Task.Run( () => MyAsyncFunction(...));
// if desired: do other things
DoSomethingElse();
// now you need the result of the async function
asyncTask.Wait();
var returnValue = asyncTask.Result;
Process(returnvalue);
}