The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.01 - entity-framework

This is function that takes two List<int> and update corresponding tables at database. When I run both functions using threads T1 and T2 , then it shows me exception at the second foreach loop:
"The ObjectContext instance has been disposed and can no longer be
used"
I already used query like
var res = ctx.EmailDBs.Include(x => x.EmailDBid == id);
but it's not working.
Please share something to persist the ctx connection until both methods are executed.
public static void UpdateEmail(List<int> invalidEmailToUpdate, List<int> validEmailToUpdate)
{
using (OnliveMTAEntities ctx = new OnliveMTAEntities())
{
Thread T1, T2;
T1 = new Thread(() =>
{
foreach (int id in invalidEmailToUpdate)
{
var res = ctx.EmailDBs.FirstOrDefault(x => x.EmailDBid == id);
res.Status = 6;
}
});
T1.Start();
Thread.Sleep(100);
T2 = new Thread(() =>
{
foreach (int id in validEmailToUpdate)
{
var res = ctx.EmailDBs.FirstOrDefault(x => x.EmailDBid == id);
res.Status = 7;
}
});
T2.Start();
ctx.SaveChanges();
}
}

You need to wait until both threads T1 and T2 are fully completed. Only then you can save dataContext ctx.SaveChanges();
For that purpose is method called Join() (MSDN). Use it like that:
// previous code here
T2.Start();
// wait for threads to be done
T1.Join();
T2.Join();
// now both of them are done
ctx.SaveChanges();
// end of using(...) and other code
EDIT: I forgot to mention: using both Join(), you can get rid of Thread.Sleep(100);. I believe that this is the reason why you got error on second thread. That call will pause execution of current thread (which will start T2) for 100ms and during that time T1 succeded to complete it's work.

Related

AspNet Boilerplate Parallel DB Access through Entity Framework from an AppService

We are using ASP.NET Zero and are running into issues with parallel processing from an AppService. We know requests must be transactional, but unfortunately we need to break out to slow running APIs for numerous calls, so we have to do parallel processing.
As expected, we are running into a DbContext contingency issue on the second database call we make:
System.InvalidOperationException: A second operation started on this context
before a previous operation completed. This is usually caused by different
threads using the same instance of DbContext, however instance members are
not guaranteed to be thread safe. This could also be caused by a nested query
being evaluated on the client, if this is the case rewrite the query avoiding
nested invocations.
We read that a new UOW is required, so we tried using both the method attribute and the explicit UowManager, but neither of the two worked.
We also tried creating instances of the referenced AppServices using the IocResolver, but we are still not able to get a unique DbContext per thread (please see below).
public List<InvoiceDto> CreateInvoices(List<InvoiceTemplateLineItemDto> templateLineItems)
{
List<InvoiceDto> invoices = new InvoiceDto[templateLineItems.Count].ToList();
ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
Parallel.ForEach(templateLineItems, async (templateLineItem) =>
{
try
{
XAppService xAppService = _iocResolver.Resolve<XAppService>();
InvoiceDto invoice = await xAppService
.CreateInvoiceInvoiceItem();
invoices.Insert(templateLineItems.IndexOf(templateLineItem), invoice);
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
});
if (exceptions.Count > 0) throw new AggregateException(exceptions);
return invoices;
}
How can we ensure that a new DbContext is availble per thread?
I was able to replicate and resolve the problem with a generic version of ABP. I'm still experiencing the problem in my original solution, which is far more complex. I'll have to do some more digging to determine why it is failing there.
For others that come across this problem, which is exactly the same issue as reference here, you can simply disable the UnitOfWork through an attribute as illustrated in the code below.
public class InvoiceAppService : ApplicationService
{
private readonly InvoiceItemAppService _invoiceItemAppService;
public InvoiceAppService(InvoiceItemAppService invoiceItemAppService)
{
_invoiceItemAppService = invoiceItemAppService;
}
// Just add this attribute
[UnitOfWork(IsDisabled = true)]
public InvoiceDto GetInvoice(List<int> invoiceItemIds)
{
_invoiceItemAppService.Initialize();
ConcurrentQueue<InvoiceItemDto> invoiceItems =
new ConcurrentQueue<InvoiceItemDto>();
ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
Parallel.ForEach(invoiceItemIds, (invoiceItemId) =>
{
try
{
InvoiceItemDto invoiceItemDto =
_invoiceItemAppService.CreateAsync(invoiceItemId).Result;
invoiceItems.Enqueue(invoiceItemDto);
}
catch (Exception e)
{
exceptions.Enqueue(e);
}
});
if (exceptions.Count > 0) {
AggregateException ex = new AggregateException(exceptions);
Logger.Error("Unable to get invoice", ex);
throw ex;
}
return new InvoiceDto {
Date = DateTime.Now,
InvoiceItems = invoiceItems.ToArray()
};
}
}
public class InvoiceItemAppService : ApplicationService
{
private readonly IRepository<InvoiceItem> _invoiceItemRepository;
private readonly IRepository<Token> _tokenRepository;
private readonly IRepository<Credential> _credentialRepository;
private Token _token;
private Credential _credential;
public InvoiceItemAppService(IRepository<InvoiceItem> invoiceItemRepository,
IRepository<Token> tokenRepository,
IRepository<Credential> credentialRepository)
{
_invoiceItemRepository = invoiceItemRepository;
_tokenRepository = tokenRepository;
_credentialRepository = credentialRepository;
}
public void Initialize()
{
_token = _tokenRepository.FirstOrDefault(x => x.Id == 1);
_credential = _credentialRepository.FirstOrDefault(x => x.Id == 1);
}
// Create an invoice item using info from an external API and some db records
public async Task<InvoiceItemDto> CreateAsync(int id)
{
// Get db record
InvoiceItem invoiceItem = await _invoiceItemRepository.GetAsync(id);
// Get price
decimal price = await GetPriceAsync(invoiceItem.Description);
return new InvoiceItemDto {
Id = id,
Description = invoiceItem.Description,
Amount = price
};
}
private async Task<decimal> GetPriceAsync(string description)
{
// Simulate a slow API call to get price using description
// We use the token and credentials here in the real deal
await Task.Delay(5000);
return 100.00M;
}
}

Entity Framework Core - Save Changes for only Certain DBSet

I'm trying to overwrite the SaveChanges method to only save changes for a particular entity.
So I want to call DB.SaveChanges<MyEntity>();
However, I don't want to lose all the previous changes that may have occurred on the given context.
I'm working on something like below, but my objects values (current) aren't being set back to before.
What needs to change?
public async Task<int> SaveChanges<T>() where T : class
{
var original = (from et in this.ChangeTracker.Entries()
where !typeof(T).IsAssignableFrom(et.Entity.GetType()) && et.State != EntityState.Unchanged
group et by new { et.State, et.CurrentValues } into grp
select new
{
key = grp.Key.State,
values = grp.Key.CurrentValues,
data = grp
}).ToList();
foreach (var entry in this.ChangeTracker.Entries().Where(x => !typeof(T).IsAssignableFrom(x.Entity.GetType())))
{
entry.State = EntityState.Unchanged;
}
var rows = await base.SaveChangesAsync();
foreach (var state in original)
{
foreach (var entry in state.data)
{
entry.State = state.key;
entry.CurrentValues.SetValues(state.values);
}
}
return rows;
}

How to do I show progress when using Reactive Extensions in C#

Am using reactive extensions in C# to perform some calculations. Here is how my code looks like so far. I have tried to wrap the code around so that I can show progress while to executing a series of tasks within my Calculate method
Here is the observable
IObservable<ResultWithProgress<SampleResult>> Calculate(){
return Observable.Create<ResultWithProgress<SampleResult>>(obs => {
var someTask = DoSomeTask1();
obs.OnNext(new ResultWithProgress(){Progress = 25, ProgressText ="Completed Task1"});
var someOtherTask = DoSomeMoreTask();
obs.OnNext(new ResultWithProgress(){Progress = 50, ProgressText ="Completed Task2"});
var calcResult = DoSomeMoreTask2();
obs.OnNext(new ResultWithProgress(){Progress = 75, ProgressText = "Completed Task3"});
var calcResult = FinalCalc();
obs.OnNext(new ResultWithProgress(){Progress = 100, ProgressText ="Completed Task4", Result = calcResult});
obs.OnCompleted();
}
}
Result Class wrapping progress and result
class ResultWithProgress<T>{
public int Progress {get; set;}
public Result T {get; set;}
public string ProgressText {get; set;}
}
Result object which contains the final result
class SampleResult{}
Usage:
Calculate().Subscribe(resultWithProgress => {
if(resultWithProgress.Result == null) //Show progress using resultWithProgress.Progress
else // get the result
})
I somehow feel that this might not the best way to do it. It feels that creating ResultWithProgress object many times without the Result seems like a code smell, especially if I have more than 10 tasks that I want to do within my Calculate()
I would appreciate it if you can give me any pointers on how to use this or am I approaching this problem wrongly?
This answer uses the same principles Enigmativity's answer discusses.
This version uses the async overload of Create.
It also makes use of the .NET 4.5 IProgress instead of a raw Action<T> to report progress.
struct CalculationProgress
{
public int Progress { get; private set; }
public string ProgressText { get; private set; }
public CalculationProgress(int progress, string progressText)
: this()
{
Progress = progress;
ProgressText = progressText;
}
}
public IObservable<Result> Calculate(IProgress<CalculationProgress> progress)
{
return Observable.Create<Result>((observer, cancellationToken) =>
{
// run the work on a background thread
// so we do not block the subscriber
// and thus the subscriber has a chance
// to unsubscribe (and cancel the work if desired)
return Task.Run(() =>
{
DoSomeTask1();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(25, "First task"));
DoSomeTask2();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(50, "Second task"));
DoSomeTask3();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(75, "third task"));
var result = DoFinalCalculation();
cancellationToken.ThrowIfCancellationRequested();
progress.Report(new CalculationProgress(100, "final task"));
observer.OnNext(result);
}, cancellationToken);
});
}
It took me some time to actually get your code to run. There were numerous syntax errors, but most importantly your Observable.Create did not have a return value.
Observable.Create should create an observable that the obs variable subscribes to and you return that IDisposable. That's so a subscriber can terminate the observable before it has completed.
Your observable directly interacts with the obs and finally calls obs.OnComplete() before the Observable.Create is completed. This means that there is no opportunity for the calling subscriber to terminate the computation because it has completed before the subscription has finished!
What you need is a way to build an observable within the Observable.Create to make it behave properly.
Now, since you are trying to return progress during your computation you are expecting side-effects. So it is easier to inject state at the beginning and just have a pure observable otherwise.
Here's how I might go about doing this.
First I change the signature of Calculate to become:
IObservable<string> Calculate(Action<ResultWithProgress<string>> progress)
Now I am injecting an action that I can use to report on my progress.
Here's how the call to Calculate might look:
Calculate(rwp => Console.WriteLine(rwp)).Subscribe(result => { });
Now here's the full Calculate method:
public IObservable<string> Calculate(Action<ResultWithProgress<string>> progress)
{
return Observable.Create<string>(obs =>
{
// This action just removes duplication from the query below
// and has the purpose of safely calling `progress`
Action<int, string, string> report = (pv, r, pt) =>
{
var p = progress;
if (p != null)
{
p(new ResultWithProgress<string>()
{
Progress = pv,
Result = r,
ProgressText = pt,
});
}
};
var query =
from someTask in Observable.Start(() => DoSomeTask1())
.Do(x => report(25, x, "Completed Task1"))
from someOtherTask in Observable.Start(() => DoSomeMoreTask())
.Do(x => report(50, x, "Completed Task2"))
from calcResultX in Observable.Start(() => DoSomeMoreTask2())
.Do(x => report(75, x, "Completed Task3"))
from calcResult in Observable.Start(() => DoSomeTask1())
.Do(x => report(100, x, "Completed Task4"))
select calcResult;
return query.Subscribe(obs);
});
}

Switch vs SelectMany + TakeUntil

I'm writing an operator that effectively does the same as Switch plus some other stuff. I always understood Switch to effectively be a neat wrapper around SelectMany combined with TakeUntil. However whilst implementing my new extension I've noticed something different about the order of creation/disposal of inner sequences. I'm wondering how I can replicate the order Switch works in since it seems likely we'd always want to dispose the existing inner before creating a new one.
I've written 2 tests to illustrate what I mean.
StandardSwitch will give the following output:
Disposing Inner followed by Creating New Inner
HandCrankedSwitch will give:
Creating New Inner,
Disposing Inner
See example code below:
[TestMethod]
public void StandardSwitch()
{
var outer = Observable.Interval(TimeSpan.FromSeconds(1))
.Do(x => Console.WriteLine("New Outer Value is {0}", x));
var wait = new CountdownEvent(8);
outer
.Select(CreateInner)
.Switch()
.Subscribe(x =>
{
Console.WriteLine("Subscriber Got {0}", x);
wait.Signal();
});
wait.Wait();
Console.WriteLine("Done");
}
[TestMethod]
public void HandCrankedSwitch()
{
var outer = Observable.Interval(TimeSpan.FromSeconds(1))
.Do(x => Console.WriteLine("New Outer Value is {0}", x));
var wait = new CountdownEvent(8);
outer.Publish(x => x.Select(CreateInner).SelectMany(xs => xs.TakeUntil(x)))
.Subscribe(x =>
{
Console.WriteLine("Subscriber Got {0}", x);
wait.Signal();
});
wait.Wait();
Console.WriteLine("Done");
}
internal IObservable<long> CreateInner(long notUsed)
{
return Observable.Create<long>(obs =>
{
Console.WriteLine("Creating New Inner");
var compDis = new CompositeDisposable {Disposable.Create(() => Console.WriteLine("Disposing Inner"))};
var dis = Observable.Interval(TimeSpan.FromSeconds(0.4))
.Do(x => Console.WriteLine("New Inner Value is {0}", x))
.Subscribe(obs);
compDis.Add(dis);
return compDis;
});
}

How can I create an Rx observable which stops publishing events when the last observer unsubscribes?

I'll create an observable (through a variety of means) and return it to interested parties, but when they're done listening, I'd like to tear down the observable so it doesn't continue consuming resources. Another way to think of it as creating topics in a pub sub system. When no one is subscribed to a topic any more, you don't want to hold the topic and its filtering around anymore.
Rx already has an operator to suit your needs - well two actually - Publish & RefCount.
Here's how to use them:
IObservable xs = ...
var rxs = xs.Publish().RefCount();
var sub1 = rxs.Subscribe(x => { });
var sub2 = rxs.Subscribe(x => { });
//later
sub1.Dispose();
//later
sub2.Dispose();
//The underlying subscription to `xs` is now disposed of.
Simple.
If I have understood your question you want to create the observable such that when all subscribers have disposed their subscription i.e there is no more subscriber, then you want to execute a clean up function which will stop the observable from production further values.
If this is what you want then you can do something like below:
//Wrap a disposable
public class WrapDisposable : IDisposable
{
IDisposable disp;
Action act;
public WrapDisposable(IDisposable _disp, Action _act)
{
disp = _disp;
act = _act;
}
void IDisposable.Dispose()
{
act();
disp.Dispose();
}
}
//Observable that we want to clean up after all subs are done
public static IObservable<long> GenerateObs(out Action cleanup)
{
cleanup = () =>
{
Console.WriteLine("All subscribers are done. Do clean up");
};
return Observable.Interval(TimeSpan.FromSeconds(1));
}
//Wrap the observable
public static IObservable<T> WrapToClean<T>(IObservable<T> obs, Action onAllDone)
{
int count = 0;
return Observable.CreateWithDisposable<T>(ob =>
{
var disp = obs.Subscribe(ob);
Interlocked.Increment(ref count);
return new WrapDisposable(disp,() =>
{
if (Interlocked.Decrement(ref count) == 0)
{
onAllDone();
}
});
});
}
//Usage example:
Action cleanup;
var obs = GenerateObs(out cleanup);
var newObs = WrapToClean(obs, cleanup);
newObs.Take(6).Subscribe(Console.WriteLine);
newObs.Take(5).Subscribe(Console.WriteLine);