1

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?

Vyrotek
  • 5,356
  • 5
  • 45
  • 70

3 Answers3

2

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
  • 213,145
  • 36
  • 401
  • 431
  • Can I ask why I need to call the EndXXX if I'm not expecting anything back? – Vyrotek Aug 26 '10 at 21:04
  • 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 Aug 26 '10 at 21:06
  • How can I do this? obj.BeginSaveChanges(obj.EndSaveChanges(asyncResult???), null); The BeginSaveChanges returns the asyncResult that I need to pass to it. – Vyrotek Aug 26 '10 at 21:11
  • 1
    @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 Aug 26 '10 at 21:19
1

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
  • 68,005
  • 14
  • 144
  • 156
  • There isn't, changing it to SaveChanges() works fine every time. I'm running a very simple test in a loop. – Vyrotek Aug 26 '10 at 21:09
  • 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 Aug 30 '10 at 02:16
0

Using the new C# 5 async/await feature seems like it will be the best way to perform fire and forget method calls.

What's the new C# await feature do?

Community
  • 1
  • 1
Vyrotek
  • 5,356
  • 5
  • 45
  • 70