public void GetNextBatchShouldBlockFileAccess()
        {
            using (var testScope = new TestScope(scope))
            {
                CancellationTokenSource cancelTokenSource1 = new CancellationTokenSource();
                CancellationTokenSource cancelTokenSource2 = new CancellationTokenSource();

                try
                {
                    var store = new FileOptimisticDataStore(Path.GetTempPath());
                    store.GetNextBatch(scope, batch); // create the file

                    CancellationToken cancelToken1 = cancelTokenSource1.Token;
                    Task task1 = Task.Factory.StartNew(() =>
                    {
                        do
                            store.GetNextBatch(scope, batch);
                        while (!cancelToken1.IsCancellationRequested);
                    }, cancelToken1);

                    CancellationToken cancelToken2 = cancelTokenSource2.Token;
                    Task task2 = Task.Factory.StartNew(() =>
                    {
                        do
                        {
                            try
                            {
                                testScope.ReadCurrentPersistedValue();
                            }
                            catch (IOException e)
                            {
                                if (e.Message.Equals("The process cannot access the file '" + testScope.FilePath + "' because it is being used by another process."))
                                    return;
                                throw;
                            }
                        }
                        while (!cancelToken2.IsCancellationRequested);
                    }, cancelToken2);

                    if (task2.Wait(3000) && !task2.IsFaulted)
                        Assert.Pass();
                    else
                    {
                        if (task2.IsFaulted)
                            Assert.Inconclusive("The second thread failed with error '" + task2.Exception.ToString() + "'.");
                        else
                            Assert.Inconclusive("The second thread was not blocked in an interval of 3000 ms.");
                    }
                }
                catch
                {
                    cancelTokenSource1.Cancel();
                    cancelTokenSource2.Cancel();
                    throw;
                }
            }
        }
 public void GetNextBatchShouldReturnMinusOneWhenBlocked()
 {
     using (var testScope = new TestScope(scope))
     {
         var store = new FileOptimisticDataStore(Path.GetTempPath());
         store.GetNextBatch(scope, batch);
         using (FileStream stream = File.Open(testScope.FilePath, FileMode.Open, FileAccess.Read, FileShare.None))
             Assert.AreEqual(-1, store.GetNextBatch(scope, batch));
     }
 }
 public void ShouldCreateFileOnFirstAccess()
 {
     using (var testScope = new TestScope(scope))
     {
         var store = new FileOptimisticDataStore(Path.GetTempPath());
         store.GetNextBatch(scope, batch);
         Assert.IsTrue(File.Exists(testScope.FilePath));
         Assert.AreEqual(testScope.ReadCurrentPersistedValue(), FileOptimisticDataStore.SeedValue + batch);
     }
 }