我想等待lambda函数的返回并返回结果

时间:2017-11-23 06:39:19

标签: c# asynchronous async-await task

考虑以下代码示例,

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很快完成。它应该从远程服务器请求数据,然后在返回这样的数据时调用回调,这可能需要几秒到几分钟。

1 个答案:

答案 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();
    }
}