Xamarin异步方法无法将其移动到自己的类

时间:2014-09-18 13:11:10

标签: c# android asynchronous android-asynctask xamarin

我正在尝试清理我的代码并把东西放在课堂上(我知道从一开始就应该做的事情)。但是我遇到了async Task的问题。

我有以下async方法,它最初与该方法的调用位于同一个类中,即不需要实例化,我只是调用方法,它异步运行,一切正常。

但是,我现在已将此async方法移动到一个新类,我打算将所有方法都放在数据库中。所以,现在我创建一个新类的实例并调用该方法,但它似乎挂断了而不去任何地方。

这是使用asnyc方法的新类:

public class ParseDBQuery
{
    public string DBcompanyName { get; set; }
    public string DBofferTitle { get; set; }
    public string DBlatitude { get; set; }
    public string DBlongitude { get; set; }
    public string DBofferDescription { get; set; }
    public string DBlogoURL { get; set; }

    public async Task getUserCoupons()
    {
        try{

            var query = ParseObject.GetQuery("userCoupons").WhereEqualTo("userObjectID", ParseUser.CurrentUser).Include("couponsObjectID");

            IEnumerable<ParseObject> MyResults =  await query.FindAsync();

            foreach (var result in MyResults)
            {
                var couponObject = result.Get<ParseObject>("couponsObjectID");

                DBcompanyName = couponObject.Get<string>("entityName");
                Console.WriteLine ("The company name is......... " + DBcompanyName);

                DBofferTitle = couponObject.Get<string>("offerTitle");
                Console.WriteLine ("The offer title is......... " + DBofferTitle);

                DBofferDescription = couponObject.Get<string>("offerDescription");
                Console.WriteLine ("The offer title is......... " + DBofferDescription);

                DBlogoURL = couponObject.Get<string>("logoURL");
                Console.WriteLine ("The logo URL is......... " + DBlogoURL);

                DBlatitude = couponObject.Get<string>("latitude");
                Console.WriteLine ("The latitude is......... " + DBlatitude);

                DBlongitude = couponObject.Get<string>("longitude");
                Console.WriteLine ("The longitude is......... " + DBlongitude);

            }

        }
        catch (ParseException e) {
            Console.WriteLine ("There was a problem fetching getUserCoupon data from parse - ParseDBQuery class");

        }

    }
}

这是实例化并调用方法:

ParseDBQuery myQuery = new ParseDBQuery ();
Task myTask = myQuery.getUserCoupons ();
//myTask.Wait ();

在这里你可以看到我尝试了Wait()方法,这就是它停止的地方。如果我删除Wait()方法,代码会在从async方法获取值之前继续(显然是因为await)。问题似乎出现在现在生活方法的新类中。如果我在其中一个查询上设置断点,例如

DBcompanyName = couponObject.Get<string>("entityName");

......它永远不会打破断点。所以问题出在某处,但我不知道为什么。

奇怪的是,如果我只是把整个方法放回到与方法调用相同的类中,没有实例化,它就完美了! 有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这是常见的死锁情况that I describe on my blog

async方法等待任务时,默认情况下await将捕获&#34;当前上下文&#34;并使用它来恢复async方法。在这种情况下,该上下文是UI上下文,它与单个UI线程相关联。当您的代码阻塞任务时(通过调用Wait),它会阻止UI线程。 FindAsync任务完成后,async getUserCoupons方法会尝试在UI线程上恢复,但由于UI线程被阻止,因此无法恢复。

顺便说一下,当代码在Main类中时(当你的代码可能在Wait返回的任务上调用FindAsync)时它会起作用,因为FindAsync没有恢复捕获的上下文。

理想的解决方案是使用await代替Wait。这意味着调用getUserCoupons的方法必须变为async,其调用方应使用await并成为async等等。async的增长是完全自然的,应该被接受。理想情况下,你想要一直“异步”#34 ;;我更多地将这个概念描述为in an MSDN article