Доброго времени суток,
столкнулась с проблемой и к своему стыду никак не могу сама найти выход из нее. Общее описание желаемого — хочется сделать сборку dataprovider'а на основании IsolatedStorage который будет предоставлять возможность асинхронного получения и сохранения данных. В его задачи входит само инициализация — создание структуры каталогов и файлов, и копирование справочных данных внедренных сборку в соответствующие файлы iso. На MSDN есть справка по поводу асинхронных io операций:
Исходя из нее был написан следующий код:
public Store()
{
// десереализуем конфигурационный файл с описанием требуемой файловой структуры
var assembly = Assembly.GetExecutingAssembly();
var setupData = String.Empty;
using (var stream = assembly.GetManifestResourceStream(this.GetResourceName("setup.json")))
using (var reader = new StreamReader(stream))
setupData = reader.ReadToEnd();
this.structure = JsonConvert.DeserializeObject<FileStructure>(setupData.ToString());
this.store = IsolatedStorageFile.GetStore(scope, null, null);
#if DEBUG
var path =
this.store.GetType()
.GetField("m_RootDir", BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(store)
.ToString();
System.Diagnostics.Debug.WriteLine(
"Путь {1}", this.store.AssemblyIdentity, path);
#endif
// создаем структуру каталогов
foreach (var entity in
this.structure.Entities.Where(x => x.Value.Type == FileStructureItemType.Directory))
if (!this.store.DirectoryExists(entity.Value.Path))
this.store.CreateDirectory(entity.Value.Path);
// создаем необходимые файлы, в случае если имеется одноименный embedded ресурс, копируем его содержание
var resources = assembly.GetManifestResourceNames();
var asyncJobs = new List<Task>();
foreach (var entity in
this.structure.Entities.Where(x => x.Value.Type == FileStructureItemType.File))
{
if (!this.store.FileExists(entity.Value.Path))
{
if (resources.Contains(this.GetResourceName(entity.Value.Path)))
{
asyncJobs.Add(this.CopyEmbeddedData(entity.Value.Path));
}
else asyncJobs.Add(Task.Factory.StartNew(
() => { using(this.store.CreateFile(entity.Value.Path)); }));
}
}
Task.WaitAll(asyncJobs.ToArray());
#if DEBUG// && CleanOnCreate
((Action<DirectoryInfo>)(dir =>
{
dir.GetDirectories().ToList().ForEach(x => x.Delete(true));
dir.GetFiles().ToList().ForEach(x => x.Delete());
}))(new DirectoryInfo(path));
Console.WriteLine("DONE!");
#endif
}
код метода CopyEmbeddedData
private async Task CopyEmbeddedData(string name) {
var assembly = Assembly.GetExecutingAssembly();
using (var embedded = assembly.GetManifestResourceStream(this.GetResourceName(name))) {
using(var stream = this.store.CreateFile(name)) {
await embedded.CopyToAsync(stream);
}
}
}
пытаясь проверить работоспособность конструктора произвожу многократное создание объекта:
Enumerable.Range(1, 10).ToList().ForEach(x => new Store()); Console.ReadLine();
Проблема заключается в том, что условно на 30 запусков, происходит "зависание" (deadlock?) выполнения. При принудительном прерывании выполнения из студи, вижу, что остановка происходит на выполнении создания файла в методе CopyEmbeddedData :
using(var stream = this.store.CreateFile(name))
Помогите пожалуйста разобраться, что я делаю не так