我正在尝试清理我的代码并把东西放在课堂上(我知道从一开始就应该做的事情)。但是我遇到了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");
......它永远不会打破断点。所以问题出在某处,但我不知道为什么。
奇怪的是,如果我只是把整个方法放回到与方法调用相同的类中,没有实例化,它就完美了! 有什么想法吗?
答案 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。