C# 任务内的实例变量为null。运行
更新:C# 任务内的实例变量为null。运行,c#,asynchronous,task-parallel-library,async-await,c#-5.0,C#,Asynchronous,Task Parallel Library,Async Await,C# 5.0,更新: public MobileServiceUser CurrentMsUser { get; private set; } 我有一个实例属性CurrentMsUser,该属性已填充,我试图在异步方法中引用它,但由于某种原因,它在方法中为null。我在属性setter上设置了一个断点,并且它从来没有设置为null,因此我相当确定该属性永远不会变为null。异步方法返回后,它再次出现。似乎只要我在匿名异步方法中,我就无法访问该属性。以下是我的方法: public async Task Cr
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);
}
该变量似乎是线程局部变量,这就是为什么它的值只能在主线程中访问 在移动到后台线程之前,应该在主线程中获取该变量的值,以避免此问题
public async Task CreateOrRetrieveAppUserAsync()
{
var userId = CurrentMsUser.UserId;
await Task.Run (async () => {
//...
//use userId here
});
}
当然,考虑到您似乎没有任何长时间运行的CPU绑定工作,并且这里的所有工作都已经是基于异步任务的IO工作,您应该能够简单地删除任务。完全运行调用,允许您在UI线程中运行少量CPU绑定工作,由于长时间运行的操作都已经是异步的,所以根本不会阻塞它
哦,因为您只需要userscolection
的第一项,所以应该使用first
,而不是ToList
,以避免将整个结果集具体化到内存中。您还应该先执行和筛选,然后再调用ToCollectionAsync
,如果可能的话,通过查询提供程序执行所有这些筛选,而不是将整个集合具体化到应用程序中。该变量似乎是线程本地变量,这就是为什么它的值只能在主线程中访问
在移动到后台线程之前,应该在主线程中获取该变量的值,以避免此问题
public async Task CreateOrRetrieveAppUserAsync()
{
var userId = CurrentMsUser.UserId;
await Task.Run (async () => {
//...
//use userId here
});
}
当然,考虑到您似乎没有任何长时间运行的CPU绑定工作,并且这里的所有工作都已经是基于异步任务的IO工作,您应该能够简单地删除任务。完全运行调用,允许您在UI线程中运行少量CPU绑定工作,由于长时间运行的操作都已经是异步的,所以根本不会阻塞它
哦,因为您只需要userscolection
的第一项,所以应该使用first
,而不是ToList
,以避免将整个结果集具体化到内存中。您还应该先执行和筛选,然后再调用ToCollectionAsync
,如果可能的话,通过查询提供程序执行所有这些筛选,而不是将整个集合具体化到应用程序中。该变量似乎是线程本地变量,这就是为什么它的值只能在主线程中访问
在移动到后台线程之前,应该在主线程中获取该变量的值,以避免此问题
public async Task CreateOrRetrieveAppUserAsync()
{
var userId = CurrentMsUser.UserId;
await Task.Run (async () => {
//...
//use userId here
});
}
当然,考虑到您似乎没有任何长时间运行的CPU绑定工作,并且这里的所有工作都已经是基于异步任务的IO工作,您应该能够简单地删除任务。完全运行调用,允许您在UI线程中运行少量CPU绑定工作,由于长时间运行的操作都已经是异步的,所以根本不会阻塞它
哦,因为您只需要userscolection
的第一项,所以应该使用first
,而不是ToList
,以避免将整个结果集具体化到内存中。您还应该先执行和筛选,然后再调用ToCollectionAsync
,如果可能的话,通过查询提供程序执行所有这些筛选,而不是将整个集合具体化到应用程序中。该变量似乎是线程本地变量,这就是为什么它的值只能在主线程中访问
在移动到后台线程之前,应该在主线程中获取该变量的值,以避免此问题
public async Task CreateOrRetrieveAppUserAsync()
{
var userId = CurrentMsUser.UserId;
await Task.Run (async () => {
//...
//use userId here
});
}
当然,考虑到您似乎没有任何长时间运行的CPU绑定工作,并且这里的所有工作都已经是基于异步任务的IO工作,您应该能够简单地删除任务。完全运行调用,允许您在UI线程中运行少量CPU绑定工作,由于长时间运行的操作都已经是异步的,所以根本不会阻塞它
哦,因为您只需要userscolection
的第一项,所以应该使用first
,而不是ToList
,以避免将整个结果集具体化到内存中。您还应该先执行和过滤,然后再调用ToCollectionAsync
,如果可能的话,通过查询提供程序执行所有过滤,而不是将整个集合具体化到应用程序中。出于好奇,为什么要将所有这些逻辑包装到一个新任务中?因为该方法是从UI线程调用的,它到底是空的?这似乎是在设置CurrentRwUser
的值,所以在调用此方法之前,我假设它为null?你是说赋值后还是空的?你是怎么决定的?在InsertUserAsync
中是否为空?如果在该方法的末尾抛出一个Debug.WriteLine(CurrentRwUser.UserId)
,它是否抛出一个NullReferenceException
?它运行的线程应该是无关的。如果长时间运行的操作是异步的,UI在运行时将保持响应。编辑:我的输入错误。是CurrentMsUser变为null,而不是CurrentRwUser@MattBurland-如果我打断了这个方法的开头大括号,它就出现了,但是只要我进入Task.Run调用中的匿名方法,它就为null。如果我运行调试状态