更新:
public MobileServiceUser CurrentMsUser { get; private set; }
我有一个实例属性CurrentMsUser
,它已填充并且我试图在异步方法中引用它,但由于某种原因它在方法中为null。我在属性setter上设置了一个断点,它永远不会被设置为null,所以我很确定该属性永远不会变为null。异步方法返回后再次出现。似乎只要我在匿名异步方法中,我就无法访问该属性。这是我的方法:
public async Task CreateOrRetrieveAppUserAsync()
{
await Task.Run (async () => {
try {
var usersCollection = await _userTable.ToCollectionAsync ();
var users = usersCollection.
Where(x =>
x.FacebookToken == CurrentMsUser.UserId).
ToList();
if (users.Count == 1) {
CurrentRwUser = users [0];
} else {
CurrentRwUser = new User {
FacebookToken = CurrentMsUser.UserId,
GoogleToken = "test",
TwitterToken = "test",
MicrosoftToken = "test",
Email = "test@gmail.com",
FacebookId = App.FacebookProvider.GetCurrentUserId (),
Name = App.FacebookProvider.GetCurrentUserName ()
};
await InsertUserAsync (CurrentRwUser);
await SyncAsync();
}
} catch (Exception ex) {
Debug.WriteLine ("CreateOrRetrieveAppUser failed: {0}", ex.Message);
}
}).ConfigureAwait(continueOnCapturedContext:false);
}
答案 0 :(得分:3)
看来该变量是线程本地的,这就是为什么它的值只能在主线程中访问。
在移动到后台线程之前,您应该在主线程中获取该变量的值以避免此问题。
public async Task CreateOrRetrieveAppUserAsync()
{
var userId = CurrentMsUser.UserId;
await Task.Run (async () => {
//...
//use userId here
});
}
当然,鉴于您似乎没有任何长时间运行的 CPU绑定工作,并且您在此处的所有工作都已经是基于异步任务的IO工作,您< em>应该能够简单地完全删除Task.Run
调用,允许你做的小CPU绑定工作必须在UI线程中运行,而不会阻止它到期对于长时间运行的操作,所有操作都已异步。
哦,因为你只需要usersCollection
的第一项,你应该使用First
,而不是ToList
,以避免将整个结果集实现到内存中。您还应该在调用First
之前执行ToCollectionAsync
和过滤,如果可能的话,通过查询提供程序执行所有这些过滤,而不是将整个集合实现为你的申请。