将基于回调的类包装到异步类中

时间:2017-08-11 11:22:38

标签: c# .net asynchronous callback

我引用了一个使用回调而不是异步操作执行各种苛刻操作的类。例如:

class CallbackClass : SomeSdkCallbacks
{
    public void RequestData()
    {
        // We call this to request some data.
        // After some time, this will trigger OnDataReturned to be called
    }

    public void OnDataReturned(DataObject data)
    {
        // This will be called automatically with returned data via SomeSdkCallbacks
    }
}

在这个课程中有很多这种类型的结构。

我想要做的是围绕这个创建一个包装类,简化它的使用。我现在要去的结构是:

class MyWrapperClass
{
    CallbackClass CallbackClass;

    public MyWrapperClass()
    {
        this.CallbackClass = new CallbackClass();
    }

    public DataObject GetData()
    {
        this.CallbackClass.RequestData();

        // Somehow wait until this.CallbackClass.OnDataReturned is called?

        // Somehow get the data that would be passed in to this.CallbackClass.OnDataReturned()???
    }
}

结束回调的最佳方法是什么?架构成单个异步方法?

编辑:为了澄清,理想情况下,我希望将其打包成一个可以在单个请求中返回数据的方法。请参阅我的示例中的MyWrapperClass.GetData()方法,了解我的理想结构。

编辑2 :我意识到这种理想的架构是糟糕的形式。不幸的是,这是我要求的结构。

2 个答案:

答案 0 :(得分:1)

我认为这就是你想要的

 class CallbackClass<T>
        {
            private TaskCompletionSource<T> task = new TaskCompletionSource<T>();

            public void RequestData()
            {

            }

            public void OnDataReturned(T data)
            {
                task.SetResult(data);
            }

            public Task<T> Task { get { return task.Task; } }
        }

        class MyWrapperClass
        {
            public Task<DataObject> GetData()
            {
                var cls = new CallbackClass<DataObject>();

                cls.RequestData();

                return cls.Task;
            }
        }

请注意,TaskCompletionSource必须按操作进行装箱,因此您不要对两个不同的调用使用相同的操作。有了这个,您可以使用async关键字。 This可能会有所帮助

答案 1 :(得分:0)

在您的情况下,您可以在CallBackClass上添加一些事件。 像这里:

class CallbackClass : SomeSdkCallbacks
{
    public event Action<object> DataReturnedEvent;
    public void RequestData()
    {
        // We call this to request some data.
        // After some time, this will trigger OnDataReturned to be called
    }
    public void OnDataReturned(DataObject data)
    {
        DataReturnedEvent?.Invoke(data);
    }
}

您可以在包装类

中使用该事件
class MyWrapperClass
{
    CallbackClass CallbackClass;

    public MyWrapperClass()
    {
        this.CallbackClass = new CallbackClass();
        CallbackClass.DataReturnedEvent =+ ProcessData;
    }
    private void ProcessData(object Data)
    {
        //some data processing
    }
    public DataObject GetData()
    {
        this.CallbackClass.RequestData()               
    }
}