考虑以下代码示例,
public XYZ GetSomething(string pluginId, string arg1, string arg2)
{
var plugin = (PluginType)_pluginManager.GetPlugin(pluginId, false);
plugin.RegisterCallback(result =>
{
//return this object instance of type XYZ
return result;
});
plugin.RequestData(arg1, arg2);
return null;
}
如何使此方法异步并等待lambda函数的结果并返回结果而不将此方法转换为阻塞方法? RequestData
的{{1}}是非阻塞的,我无法更改它。最终返回plugin
,它是一个未包含在任何任务中的对象实例。
如何等待lambda函数中的结果然后返回结果?
修改
result
很快完成。它应该从远程服务器请求数据,然后在返回这样的数据时调用回调,这可能需要几秒到几分钟。
答案 0 :(得分:4)
要创建可与async await
一起使用的内容,您必须创建Task
。因此,您的GetSomething()
方法必须返回Task<XYZ>
。然后在下一步中,它取决于您的.RequestData()
方法的工作原理。是否阻止?由于首先注册回调的架构,我认为.RequestData()
会立即返回,完成后会调用回调。要在GetSomething()
方法中包含这些内容,您可以使用TaskCompletionSource
:
public static void Main()
{
Console.WriteLine("Starting");
Start();
Console.ReadKey();
}
public static async Task Start()
{
var result = await GetSometing("abc", "def", "ghi");
Console.WriteLine(result);
}
public static Task<int> GetSometing(string pluginId, string arg1, string arg2)
{
var plugin = new PluginMock();
var tcs = new TaskCompletionSource<int>();
plugin.RegisterCallback(result =>
{
tcs.SetResult(result);
});
plugin.RequestData(arg1, arg2);
return tcs.Task;
}
public class PluginMock
{
private Action<int> _callback;
public void RegisterCallback(Action<int> callback)
{
_callback = callback;
}
public void RequestData(string arg1, string arg2)
{
var thread = new Thread(() =>
{
Thread.Sleep(1000);
_callback(42);
});
thread.Start();
}
}