我希望能够将写入文件的代码放入互斥锁中,以避免对文件进行任何并发修改。但是,我只希望将具有特定名称的文件作为关键部分而不是其他文件。这段代码会按预期工作还是我错过了什么?
private async static void StoreToFileAsync(string filename, object data)
{
IsolatedStorageFile AppIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
if (IsolatedStorageFileExist(filename))
{
AppIsolatedStorage.DeleteFile(filename);
}
if (data != null)
{
string json = await Task.Factory.StartNew<string>(() => JsonConvert.SerializeObject(data));
if (!string.IsNullOrWhiteSpace(json))
{
byte[] buffer = Encoding.UTF8.GetBytes(json);
Mutex mutex = new Mutex(false, filename);
mutex.WaitOne();
IsolatedStorageFileStream ISFileStream = AppIsolatedStorage.CreateFile(filename);
await ISFileStream.WriteAsync(buffer, 0, buffer.Length);
ISFileStream.Close();
mutex.ReleaseMutex();
}
}
}
编辑1:或者我应该将异步写入替换为同步写入并作为单独的任务运行吗?
await Task.Factory.StartNew(() =>
{
if (!string.IsNullOrWhiteSpace(json))
{
byte[] buffer = Encoding.UTF8.GetBytes(json);
lock (filename)
{
IsolatedStorageFileStream ISFileStream = AppIsolatedStorage.CreateFile(filename);
ISFileStream.Write(buffer, 0, buffer.Length);
ISFileStream.Close();
}
}
});
答案 0 :(得分:3)
在一般情况下,使用带有异步代码的Mutex
是错误的。通常情况下,我说你应该使用类似AsyncLock
from my AsyncEx library的内容,如果你想为每个文件单独锁定,那么你需要一本字典或其他类似的字典。
但是,如果始终从UI线程调用您的方法,那么它将起作用。它不是很有效,但它会起作用。
答案 1 :(得分:2)
你应该改进一些事情:
filename
不是互斥体的好名字 - 它是全局对象(在所有进程中),所以它应该是唯一的。private async static void StoreToFileAsync(string filename, object data)
{
using (IsolatedStorageFile AppIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (IsolatedStorageFileExist(filename))
AppIsolatedStorage.DeleteFile(filename);
if (data != null)
{
string json = await Task.Factory.StartNew<string>(() => JsonConvert.SerializeObject(data));
if (!string.IsNullOrWhiteSpace(json)) await Task.Run(() =>
{
byte[] buffer = Encoding.UTF8.GetBytes(json);
using (Mutex mutex = new Mutex(false, filename))
{
try
{
mutex.WaitOne();
using (IsolatedStorageFileStream ISFileStream = AppIsolatedStorage.CreateFile(filename))
ISFileStream.Write(buffer, 0, buffer.Length);
}
catch { }
finally { mutex.ReleaseMutex(); }
}
});
}
}
}
编辑:从Mutex中删除了异步调用 - 因为它不会从UI线程调用时会导致问题。