Xamarin的Amazon IAP插件-使用TaskCompletionSource时崩溃
我正在尝试为Xamarin的Amazon IAP插件实现一个包装器。它以以下方式使用基于事件的系统: 您可以启动方法调用并侦听事件。方法调用初始化请求,其中一些请求返回响应。事件是异步系统生成的消息,发送这些消息是为了响应方法调用以将请求的数据返回给您。 我的目标是将这个基于事件的系统包装成一些API,允许我在任务中使用插件,这样我就可以使用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
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内部删除,这就像在循环列表时从列表中删除元素一样。