我有一个名为DownloadFileAsync的方法,用于下载文件,另一个名为GetLocalFilePathAsync,用于返回文件路径。
我的问题是调用GetLocalFilePathAsync而DownloadFileAsync未完成导致零字节文件和错误。
我尝试根据这个问题实现动态锁定: Creating Dynamic Locks at Runtime in ASP.NET
这是我的代码。
public static class DynamicLock
{
private static Dictionary<string, AsyncLock> LockList = new Dictionary<string, AsyncLock>();
private static readonly object lockDic = new AsyncLock();
public static void LockOnValue(string lockKey)
{
lock (lockDic)
{
AsyncLock obj = null;
if (!LockList.TryGetValue(lockKey, out obj))
{
obj = new AsyncLock();
LockList.Add(lockKey, obj);
}
Monitor.Enter(obj);
//System.Diagnostics.Debug.WriteLine($"LockList count: {LockList.Count} {lockKey} locked, Value = {obj}");
}
}
public static void UnlockOnValue(string lockKey)
{
Monitor.Exit(LockList[lockKey]);
}
}
public static async Task<string> GetLocalFilePathAsync(string itemId, string fileName)
{
var lockKey = $"{itemId}_{fileName}";
DynamicLock.LockOnValue(lockKey);
try
{
System.Diagnostics.Debug.WriteLine($"PATH ACCESS FILE {lockKey}");
if (string.IsNullOrEmpty(itemId) || string.IsNullOrEmpty(fileName))
return null;
IPlatform platform = DependencyService.Get<IPlatform>();
string recordFilesPath = Path.Combine(await platform.GetFilesPathAsync(), itemId);
var checkExists = await FileSystem.Current.LocalStorage.CheckExistsAsync(recordFilesPath);
if (checkExists == ExistenceCheckResult.NotFound)
return null;
return Path.Combine(recordFilesPath, fileName);
}
catch
{
throw;
}
finally
{
DynamicLock.UnlockOnValue(lockKey);
System.Diagnostics.Debug.WriteLine($"PATH UNLOCK {lockKey}");
}
}
public static async Task DownloadFileAsync<T>(IMobileServiceSyncTable<T> table, MobileServiceFile file)
{
var lockKey = $"{file.ParentId}_{file.Name}";
DynamicLock.LockOnValue(lockKey);
try
{
System.Diagnostics.Debug.WriteLine($"DOWNALOAD FILE {lockKey}");
var platform = DependencyService.Get<IPlatform>();
await platform.DownloadFileAsync(table, file);
}
catch
{
throw;
}
finally
{
DynamicLock.UnlockOnValue(lockKey);
System.Diagnostics.Debug.WriteLine($"DOWNALOAD UNLOCK {lockKey}");
}
}
来自日志:
DOWNALOAD FILE e7152b72-adf6-4615-b5f9-e77e3ca4345b_IMG_20160219_101743.jpg
路径访问文件e7152b72-adf6-4615-b5f9-e77e3ca4345b_IMG_20160219_101743.jpg
PATH UNLOCK e7152b72-adf6-4615-b5f9-e77e3ca4345b_IMG_20160219_101743.jpg
ERROR
因此,在DownloadFileAsyn发布锁定之前执行GetLocalFilePathAsync。
我错过了什么?
韩国社交协会
答案 0 :(得分:1)
在这里写我的问题让我重新思考它,下面的内容似乎有效(尽管我还是要彻底测试)。
public static class DynamicLock
{
private static Dictionary<string, AsyncLock> LockList = new Dictionary<string, AsyncLock>();
private static readonly object lockDic = new AsyncLock();
public static async Task<T> LockOnKey<T>(string lockKey, Func<Task<T>> criticalFunc)
{
AsyncLock obj = null;
lock (lockDic)
{
if (!LockList.TryGetValue(lockKey, out obj))
{
obj = new AsyncLock();
LockList.Add(lockKey, obj);
}
}
using (var releaser = await obj.LockAsync().ConfigureAwait(false))
{
return await criticalFunc();
}
}
}