【发布时间】:2014-12-26 12:27:11
【问题描述】:
我正在尝试在我正在创建的 windows phone 8.1 API 中实现一个简单的缓存机制。我在 Visual Studio 中选择了一个 Windows Phone 可移植类库模板。
缓存类看起来像这样,
[DataContract]
class cache
{
private const string JSONFILENAME = "data.json";
[DataMember]
Dictionary<Int32, item> cDictionary;
[DataMember]
int _maxSize;
public int MaxSize
{
get { return _maxSize; }
set { _maxSize = value; }
}
public cache(int maxSize){
cDictionary = new Dictionary<int, item>();
_maxSize = maxSize;
}
public void push(Int32 id, item obj)
{
if (!cDictionary.ContainsKey(id)) {
cDictionary.Add(id, obj);
}
}
internal static async Task<cache> Load()
{
cache obj = null;
try
{
var jsonSerializer = new DataContractJsonSerializer(typeof(cache));
using (var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME))
{
obj = (cache)jsonSerializer.ReadObject(myStream);
}
}
catch (FileNotFoundException)
{
obj = null;
}
return obj;
}
internal static async void Save(cache obj)
{
var serializer = new DataContractJsonSerializer(typeof(cache));
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(
JSONFILENAME,
CreationCollisionOption.ReplaceExisting))
{
serializer.WriteObject(stream, obj);
}
}}
其对象进入字典的项目类如下所示,
[DataContract]
class item
{
[DataMember]
string _fName;
public string FName
{
get { return _fName; }
set { _fName = value; }
}
[DataMember]
string _lName;
public string LName
{
get { return _lName; }
set { _lName = value; }
}
[DataMember]
int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
public item(int id, string fName, string lName)
{
this.Id = id;
this.FName = fName;
this.LName = lName;
}
}
想法是:最终用户创建 api 的实例并调用方法 doSomething()。该方法首先在缓存中查找(示例中未显示),如果找到,则返回 Item 对象,否则,从 Web 服务(未显示)获取项目对象,然后将其推送到缓存。
public class api
{
cache tCache;
string apiKey;
public laas(string apiKey)
{
this.apiKey = apiKey;
this.tCache = new cache(100);
}
public async void Initialize(api obj)
{
//If cache exists
obj.tCache = await cache.Load();
if (obj.tCache == null)
{
obj.tCache = new cache(100);
}
}
public void doSomething(string id)
{
tCache.push(id.GetHashCode(),new item(1,"xxxx","xxx"));
cache.Save(tCache);
}
}
我想在 api 类的构造函数中初始化/加载缓存,但由于 ApplicationData.Current.LocalFolder 仅提供从持久存储读取和写入数据的异步方法,因此我创建了一个单独的静态异步类 Initiialize()会加载缓存,因为创建异步构造函数没有意义。
问题:在doSomething( ) 抛出 空引用异常。这可能会发生,因为由于异步操作,tCache 尚未加载/初始化。
我曾尝试 obj.tCache = await cache.Load().Result 等待加载完成,但这会挂起我的应用程序。 (http://msdn.microsoft.com/en-us/magazine/jj991977.aspx)
请您在这里指出正确的方向吗?我的诊断正确吗?有更好的方法吗?任何指针表示赞赏。
谢谢!
【问题讨论】:
标签: c# windows-phone-8.1 async-await portable-class-library