Xamarin的Amazon IAP插件-使用TaskCompletionSource时崩溃

Xamarin的Amazon IAP插件-使用TaskCompletionSource时崩溃,xamarin,task-parallel-library,amazon,taskcompletionsource,Xamarin,Task Parallel Library,Amazon,Taskcompletionsource,我正在尝试为Xamarin的Amazon IAP插件实现一个包装器。它以以下方式使用基于事件的系统: 您可以启动方法调用并侦听事件。方法调用初始化请求,其中一些请求返回响应。事件是异步系统生成的消息,发送这些消息是为了响应方法调用以将请求的数据返回给您。 我的目标是将这个基于事件的系统包装成一些API,允许我在任务中使用插件,这样我就可以使用asyncwait语法。为了实现这一点,我使用了TaskCompletionSource,如下例所示: public async Task<bool

我正在尝试为Xamarin的Amazon IAP插件实现一个包装器。它以以下方式使用基于事件的系统:

您可以启动方法调用并侦听事件。方法调用初始化请求,其中一些请求返回响应。事件是异步系统生成的消息,发送这些消息是为了响应方法调用以将请求的数据返回给您。

我的目标是将这个基于事件的系统包装成一些API,允许我在任务中使用插件,这样我就可以使用
asyncwait
语法。为了实现这一点,我使用了
TaskCompletionSource
,如下例所示:

public async Task<bool> GetProductInfoAsync(params string[] productIds)
{
    var iapService = AmazonIapV2Impl.Instance;
    var tcs = new TaskCompletionSource<bool>();
    var skus = new SkusInput { Skus = productIds.ToList() };
    var requestId = iapService.GetProductData(skus).RequestId;

    GetProductDataResponseDelegator delegator = null;
    delegator = new GetProductDataResponseDelegator(response => 
    {
        if(response.Id == requestId) {
            var result = GetResultFromResponse(response);
            tcs.SetResult(result);
            //iapService.RemoveGetProductDataResponseListener(delegator.responseDelegate);
        }
    });

    iapService.AddGetProductDataResponseListener(delegator.responseDelegate);
    return await tcs.Task;
}
…这是毫无意义的

那么,这里有什么明显的我遗漏的吗?或者可能是插件的错误

我已经用上面的代码创建了一个存储库,这样您就可以重现这个问题。这是我的游乐场,所以请忽略整个项目结构,只关注课程和课程

提示1: 注释行
//iapService.RemoveGetProductDataResponseListener(delegator.responseDelegate)
还会使用相同的消息导致崩溃,但在方法的第一次调用时已经发生了

提示2:
amazonipservice
包含一个有注释的方法,它使用
wait Task.Delay(TimeSpan.frommilluses(1))
并以一种我不喜欢的非常粗糙的方式从上面解决了这个问题。

问题似乎是这些函数必须异步运行。文件中也提到了。所以,一旦你同步运行这些函数,它们就会抛出异常,我不知道库中发生了什么,但你的黑客解决方案才是真正的解决方案。如果您按照以下方式编写函数。它也起作用

  PurchaseResponseDelegator delegator = null;
                delegator = new PurchaseResponseDelegator(async response =>
                {
                    await Task.Run(() =>
                    {
                        if (response.RequestId == requestId)
                        {
                            var result = GetPurchaseEventHandler(response);
                            var sucess = taskCompletionSource.TrySetResult(result);        
                            context.RemovePurchaseResponseListener(delegator.responseDelegate);
                        }
                    } );
                });
                // Register for an event
                context.AddPurchaseResponseListener(delegator.responseDelegate);

尽管有异步等待解决方案,我还有一个异常,不知何故,它总是为行
taskCompletionSource.SetResult(result)抛出异常仅适用于PurchaseUpdates函数。如果我改为使用这一行
var suces=taskCompletionSource.TrySetResult(结果)工作正常

问题似乎是这些函数必须异步运行。文件中也提到了。所以,一旦你同步运行这些函数,它们就会抛出异常,我不知道库中发生了什么,但你的黑客解决方案才是真正的解决方案。如果您按照以下方式编写函数。它也起作用

  PurchaseResponseDelegator delegator = null;
                delegator = new PurchaseResponseDelegator(async response =>
                {
                    await Task.Run(() =>
                    {
                        if (response.RequestId == requestId)
                        {
                            var result = GetPurchaseEventHandler(response);
                            var sucess = taskCompletionSource.TrySetResult(result);        
                            context.RemovePurchaseResponseListener(delegator.responseDelegate);
                        }
                    } );
                });
                // Register for an event
                context.AddPurchaseResponseListener(delegator.responseDelegate);

尽管有异步等待解决方案,我还有一个异常,不知何故,它总是为行
taskCompletionSource.SetResult(result)抛出异常仅适用于PurchaseUpdates函数。如果我改为使用这一行
var suces=taskCompletionSource.TrySetResult(结果)它工作正常

关于RemoveGetProductDataResponseListener,可能会出现问题,因为您尝试在delagator内部删除,这就像在循环该列表时从列表中删除元素。关于RemoveGetProductDataResponseListener,可能会出现问题,因为您尝试在delagator内部删除,这就像在循环列表时从列表中删除元素一样。