Ale*_*ndr 0 c# thread-safety windows-phone-7 async-await windows-phone-8
我在Windows Phone 8应用程序中有一个本地数据库.该应用程序包含对数据库的大量查询,我不希望对UI的响应性产生不良影响.
例如,我有一个用户表和方法,用于通过id从数据库中获取用户.
目前的变种
public class CacheDataContext : DataContext
{
public static string DBConnectionString = "Data Source=isostore:/Cache.sdf";
public CacheDataContext(string connectionString)
: base(connectionString) { }
public static AutoResetEvent OperationOnDatabaseUser = new AutoResetEvent(true);
public Table<User> UserItems;
}
public class CacheDataContextUser : CacheDataContext
{
public CacheDataContextUser(string connectionString)
: base(connectionString) { }
public User GetUser(string id)
{
try
{
OperationOnDatabaseUser.WaitOne();
using (CacheDataContext context = new CacheDataContext(DBConnectionString))
{
//find user in the data base and return
}
}
finally
{
OperationOnDatabaseUser.Set();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果数据库同时允许不同的请求添加,更新,删除数据,我需要确保数据的安全性.为此,我使用AutoResetEvent.不确定我做得对,但到目前为止没有问题.
我可以从数据库中获取用户:
using (DataBaseUser = new CacheDataContextFriends(ConnectionString))
{
var user = DataBaseUser.GetUser(id);
}
Run Code Online (Sandbox Code Playgroud)
异步/ AWAIT
但我希望使用关键字async/await来处理数据库.
public class CacheDataContextUser : CacheDataContext
{
public CacheDataContextUser(string connectionString)
: base(connectionString) { }
private object threadLock = new object();
public Task<User> GetUser(string id)
{
using (CacheDataContext context = new CacheDataContext(DBConnectionString))
{
var result = await Task<User>.Factory.StartNew(() =>
{
lock (threadLock)
{
//find user in the data base and return
}
});
return result;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我害怕重写上面描述的方法,因为我不确定它是对的.请告诉我可能是什么问题.我的主要目标是提高应用程序的响应能力.
首先,AutoResetEvent使用独占访问是错误的.在Windows中,像这样的"事件"是从一个线程到另一个线程的消息; 在这种情况下,你只需要一个简单的锁:
public class CacheDataContext : DataContext
{
public static string DBConnectionString = "Data Source=isostore:/Cache.sdf";
public CacheDataContext(string connectionString)
: base(connectionString) { }
protected static readonly object OperationOnDatabaseUser = new object();
public Table<User> UserItems;
}
public class CacheDataContextUser : CacheDataContext
{
public CacheDataContextUser(string connectionString)
: base(connectionString) { }
public User GetUser(string id)
{
lock (OperationOnDatabaseUser)
{
using (CacheDataContext context = new CacheDataContext(DBConnectionString))
{
//find user in the data base and return
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果要提高响应速度,请使用Task.Run,即调用数据上下文方法:
var user = await Task.Run(() => GetUser(id));
Run Code Online (Sandbox Code Playgroud)
不要使你的数据上下文异步方法,除非实际的数据库访问是异步的(即使用EF6,没有 Task.Run).
| 归档时间: |
|
| 查看次数: |
2524 次 |
| 最近记录: |