如何同步调用异步(await)方法?

时间:2014-02-04 12:42:32

标签: c# .net asynchronous parse-platform

我正在使用parse.com提供的.NET API,

https://parse.com/docs/dotnet_guide#objects-saving

我的代码片段看起来像这样;

public async void UploadCurrentXML()
{
   ...
   var query = ParseObject.GetQuery("RANDOM_TABLE").WhereEqualTo("some_field", "string");
   var count = await query.CountAsync();
   ParseObject temp_A;
   temp_A = await query.FirstAsync();
   ...
   // do lots of stuff
   ...
   await temp_A.SaveAsync();
}

总结;查询远程数据库。从结果中,从数据库获得特定对象(或其引用)。对对象执行多个操作,最后将其保存回数据库。

所有数据库操作都通过await ParseObject.randomfunction()进行。是否可以以同步方式调用这些函数?或者至少等到操作返回而不继续?该应用程序专为维护目的而设计,操作时间不是问题。

我问这个是因为事情的原因,我得到一个错误,表明

  

正在进行的计数操作数已达到极限。

我试过了,

var count = await query.CountAsync().ConfigureAwait(false);

在所有await调用中,但它没有帮助 - 代码仍然是异步运行。

var count = query.CountAsync().Result;

导致应用程序卡住 - 相当肯定我遇到了僵局。

一些搜索让我想到了这个问题,

How would I run an async Task<T> method synchronously?

但我不明白它是如何适用于我的情况,因为我无法访问ParseObject的源代码。救命? (我使用的是.NET 4.5)

2 个答案:

答案 0 :(得分:4)

我建议您始终使用异步编程。如果您遇到某种资源问题(即,不允许对单个数据库进行多次查询),那么您应该构建代码以便不会发生(例如,在操作正在进行时禁用UI按钮)。或者,如果必须,您可以使用SemaphoreSlim来限制async代码:

private readonly SemaphoreSlim _mutex = new SemaphoreSlim(1);
public async Task UploadCurrentXMLAsync()
{
  await _mutex.WaitAsync();
  try
  {
    ...
    var query = ParseObject.GetQuery("RANDOM_TABLE").WhereEqualTo("some_field",  "string");
    var count = await query.CountAsync();
    ParseObject temp_A;
    temp_A = await query.FirstAsync();
    ...
    // do lots of stuff
    ...
    await temp_A.SaveAsync();
  }
  finally
  {
    _mutex.Release();
  }
}

但如果你真的,真的想要同步阻止,你可以这样做:

public async Task UploadCurrentXMLAsync();

Task.Run(() => UploadCurrentXMLAsync()).Wait();

同样,我不能推荐这最后一个“解决方案”,这更像是一个黑客而不是一个正确的解决方案。

答案 1 :(得分:1)

如果api方法返回异步任务,您可以获取awaiter并同步获得结果

    api.DoWorkAsync().GetAwaiter().GetResult();