views:

27

answers:

2

I noticed when performing many database transactions using BeginSaveChanges(null, null) the last query is sometimes unsuccessful. Is it because the instance of my DataContext died too quickly for the query to be performed?

When I changed my code to use the normal SaveChanges all the queries are successful.

Specifically, I'm performing queries against the Azure Table Storage using a TableServiceContext.

Edit - If the Disposing of my DataContex is the real problem. What alternatives do I have? Should I wrap making an instance of my datacontext and executing my query in a Task?

A: 

First of all, you should always call the matching EndXXX method any BeginXXX method.

Then you should make sure that you don't dispose the object you're calling a BeginXXX method before you have called the EndXXX method.


A save fire-and-forget approach (ignoring the Dispose issue) is to pass EndXXX as callback to BeginXXX:

obj.BeginXXX(callback: obj.EndXXX, state: null);
// -- or --
obj.BeginXXX(callback: asyncResult => obj.EndXXX(asyncResult), state: null);

You still need to make sure that you don't call obj.Dispose(); before all asynchronous operations finished.

dtb
Can I ask why I need to call the EndXXX if I'm not expecting anything back?
Vyrotek
It's part of the design pattern. EndXXX will throw any exception that occurred during the asynchronous operation, and will clean up and resources used. Don't omit it, even it just returns *void*.
dtb
How can I do this?obj.BeginSaveChanges(obj.EndSaveChanges(asyncResult???), null);The BeginSaveChanges returns the asyncResult that I need to pass to it.
Vyrotek
@Vyrotek: The IAsyncResult that BeginXXX returns is also passed to the callback. So it should work as shown in my answer. Alternative syntax: `obj.BeginXXX(callback: asyncResult => obj.EndXXX(asyncResult), state: null);`
dtb
+1  A: 

Well for one, if you don't call EndXXX you will never get an exception if something goes wrong. You may want to check that first to see if there's an exception being thrown in your last batch.

Josh Einstein
There isn't, changing it to SaveChanges() works fine every time. I'm running a very simple test in a loop.
Vyrotek
You shouldn't ass-u-me :) Calling SaveChanges in a loop is totally different from calling BeginSaveChanges. Maybe you're getting an exception about overloading the server? Maybe you're getting a timeout? When you use the blocking call you are inherently changing the timing. I still think you're getting an exception after the last call that succeeds.
Josh Einstein