2017-11-23 3 views
-1

를 반환, 나는이 방법 비동기을하고 람다 함수의 결과를 기다릴 수있는 방법나는 람다 함수의 반환을 기다리고 다음과 같은 코드 샘플을 고려 결과

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; 
    } 

을하고하지 않고 결과를 반환 할 이 메소드를 블로킹 메소드로 바꾸는 것? RequestDataplugin이며 비 차단이며 변경할 수 없습니다. result이 결국 반환되며 모든 작업에서 래핑되지 않은 개체 인스턴스입니다.

람다 함수의 결과를 어떻게 기다리고 결과를 반환 할 수 있습니까?

편집 : RequestData 매우 빠르게 완료됩니다. 원격 서버에서 데이터를 요청한 다음 몇 초에서 몇 분 정도 걸릴 수있는 데이터가 반환되면 콜백을 호출합니다.

+0

그냥 인수 목록 전에 "비동기"키워드를 넣어 비동기 람다 식을 표시 할 수 있습니다,하지만 난 RegisterCallback가 매개 변수로 비동기 위임을 받아 의심 : 당신의 GetSomething() 메서드 내에서이 일을 마무리하기 위해 당신은 TaskCompletionSource 사용할 수 있습니다. –

+0

@ Marc-AntoineJacob thats는 어딘가에서 기다릴 필요가 없습니다. –

+0

@ TimRutter 분명히, 그 의미는 무엇입니까. 그러나 RegisterCallback은 작업 을 기다리는 비동기 대의원을 받아들이지 않을 것입니다. –

답변

4

async await과 함께 사용할 수있는 무언가를 만들려면 Task을 만들어야합니다. 따라서 GetSomething() 메서드는 Task<XYZ>을 반환해야합니다. 다음 단계에서 귀하의 .RequestData() 방법이 어떻게 작동하는지에 따라 다릅니다. 차단 되나요? 처음으로 콜백 등록에 대한 아키텍처로 인해, 나는 .RequestData()이 즉시 반환하고 콜백이 완료되면 콜백을 호출한다고 생각할 것입니다.

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(); 
    } 
} 
+0

'RequestData'가 차단되지 않습니다. 내 질문을 편집하고 그 정보를 추가했습니다. 매우 빠르게 돌아 오지만 콜백 호출은 몇 초에서 몇 분이 걸릴 수 있습니다 ... –

+0

@MattWolf 그는 대답에서 이것을 인정했습니다. 꽤 견고하지만 작업하기에는 다소 짜증이 나는데, 새로운 스레드를 생성한다고 생각하면됩니다. –

+0

새 스레드를 만들지 않습니다. 플러그인에서 일어나는 비동기적인 작업을 모방 한'PluginMock'입니다. 사용자가해야하는 것은'GetSomething()'메소드 내에 있습니다. – Oliver

관련 문제