Пример #1
0
        /// <summary>
        /// Thread safe, runs on own thread for data lock.
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public static async Task Save(AccountDataItem account)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                // Serialize on current thread
                GetSerializer().WriteObject(stream, account);
                stream.Position = 0;

                await Task.Run(async delegate
                {
                    using (await Locks.LockAccounts())
                    {
                        // Get the account folder
                        var timeTracker       = TimeTracker.Start();
                        IFolder accountFolder = await FileHelper.GetOrCreateAccountFolder(account.LocalAccountId);
                        timeTracker.End(3, "AccountsManager.Save GetOrCreateAccountFolder");

                        // Create a temp file to write to
                        timeTracker           = TimeTracker.Start();
                        IFile tempAccountFile = await accountFolder.CreateFileAsync("TempAccountData.dat", CreationCollisionOption.ReplaceExisting);
                        timeTracker.End(3, "AccountsManager.Save creating temp file");

                        // Write the data to the temp file
                        timeTracker = TimeTracker.Start();
                        using (Stream s = await tempAccountFile.OpenAsync(StorageEverywhere.FileAccess.ReadAndWrite))
                        {
                            timeTracker.End(3, "AccountsManager.Save opening file stream");

                            timeTracker = TimeTracker.Start();
                            stream.CopyTo(s);
                            timeTracker.End(3, "AccountsManager.Save copying stream to file");
                        }

                        // Move the temp file to the actual file
                        timeTracker = TimeTracker.Start();
                        await tempAccountFile.RenameAsync(FileNames.ACCOUNT_FILE_NAME, NameCollisionOption.ReplaceExisting);
                        timeTracker.End(3, "AccountsManager.Save renaming temp file to final");
                    }
                });
            }
        }
Пример #2
0
        private static async Task <AccountDataItem> GetOrLoadHelper(Guid localAccountId)
        {
            Debug.WriteLine("GetOrLoad Account: " + localAccountId);

            CachedAccountEntry entry;

            lock (_cachedAccounts)
            {
                if (!_cachedAccounts.TryGetValue(localAccountId, out entry))
                {
                    entry = new CachedAccountEntry();
                    _cachedAccounts[localAccountId] = entry;
                }

                // Cache entry exists
                else
                {
                    // But account still might have been disposed
                    var account = entry.Account;
                    if (account != null)
                    {
                        Debug.WriteLine("Returning cached account: " + localAccountId);
                        return(account);
                    }
                }
            }

            Debug.WriteLine("GetOrLoad Account starting thread to enter data lock: " + localAccountId);

            // We'll have to enter a lock and then load it (if it's not already loaded at that point)
            return(await System.Threading.Tasks.Task.Run(async delegate
            {
                Debug.WriteLine("GetOrLoad Account acquiring lock: " + localAccountId);

                using (await Locks.LockAccounts())
                {
                    Debug.WriteLine("GetOrLoad Account acquired lock: " + localAccountId);

                    AccountDataItem account;

                    // Double check if account's already loaded (might have been loaded by the time we've entered the lock)
                    account = entry.Account;

                    if (account != null)
                    {
                        Debug.WriteLine("GetOrLoad Account, account already loaded: " + localAccountId);
                        return account;
                    }

                    Debug.WriteLine("Loading account: " + localAccountId);

                    account = await Load(localAccountId);

                    // If account doesn't exist
                    if (account == null)
                    {
                        Debug.WriteLine("Account didn't exist: " + localAccountId);
                        return null;
                    }

                    Debug.WriteLine("Loaded account: " + localAccountId);

                    entry.Account = account;

                    return account;
                }
            }));
        }