4

I'm calling my DocumentDB database to query for a person. If the person is not in the database, I'm then trying to insert the person into my collection.

When I check the collection, I see that the new person is being created but my code just seems to hang where I make the second call to insert the person into the collection. Any idea why my code is hanging? I'm not including all the code to save space e.g. GetDatabaseAsync(), GetCollectionAsync(), etc. are all working.

using (client = new DocumentClient(new Uri(endPointUrl), authorizationKey))
{
   //Get the database
   var database = await GetDatabaseAsync();

   //Get the Document Collection
   var collection = await GetCollectionAsync(database.SelfLink, "People");

   string sqlQuery = "SELECT * FROM People f WHERE f.id = \"" + user.PersonId + "\"";

   dynamic doc = client.CreateDocumentQuery(collection.SelfLink, sqlQuery).AsEnumerable().FirstOrDefault();

   if (doc == null)
   {
      // User is not in the database. Add user to the database
      try
      {
         **// This is where the code is hanging. It creates the user in my collection though!**
         await client.CreateDocumentAsync(collection.DocumentsLink, user);
      }
      catch
      {
         // Handle error
      }
   }
   else
   {
      // User is already in the system.
      user = doc;
   }
}

Is it possible that the code hangs because I'm trying to both query and insert a document inside the same USING statement.

Is it a better idea for me to create a new instance of the client and create a separate block to handle the document INSERT?

Sam
  • 26,817
  • 58
  • 206
  • 383
  • I'm not seeing any eye-popping red flags here. It should be faster to re-use the client - it avoids having to do another handshake w/ the database server. Can you give me an idea of what the timing profile looks like for this? How long does the initial query take? How long does document creation take? – Andrew Liu Nov 23 '14 at 19:51
  • After posting this question, I decided to simplify my logic so I just did the INSERT part. I'm still getting timed out. See this post: http://stackoverflow.com/questions/27086097/getting-a-task-was-cancelled-while-trying-to-create-a-document-in-documentdb?noredirect=1#comment42691065_27086097 How do I get timing profile? Do you mean, put some DateTime variable in my code to capture the exact time when the code executes each line or is there a tool that I can use to capture the timing profile? Also any idea why the DocumentDB does not return a response after the CreateDocumentAsync()? – Sam Nov 23 '14 at 20:39
  • In your call stack, is there any place where you are calling the async method from a non-async method? – Aman B Jan 28 '17 at 17:05

2 Answers2

6

If a call to an async method hangs it usually is because it being called synchronously by calling it with .Wait() or .Result instead of await ing. You have not shown your calling code, so please include it here.

Option 1: Don't call your async method synchronously. This is the right approach.

Option 2: You should use .ConfigureAwait(false) in your async calls to DocDB if you are calling this method synchronously. Try this:

var database = await GetDatabaseAsync()**.ConfigureAwait(false)**;
...
var collection = await GetCollectionAsync(database.SelfLink, "People")**.ConfigureAwait(false)**;
...
await client.CreateDocumentAsync(collection.DocumentsLink, user)**.ConfigureAwait(false)**;

Further details on ConfigureAwait

Community
  • 1
  • 1
  • Initially we did the same for our azure service fabric project, Now we converted it to web application, now same code is taking too much time. – AstroBoy Feb 25 '20 at 14:05
4

It seems there is a bug in the client SDK of DocumentDB. Try using client.CreateDocumentAsync(collection.DocumentsLink, user).Wait() instead of await client.CreateDocumentAsync(collection.DocumentsLink, user)


UPDATE: This has most probably been fixed in the latest SDK as I am not able to reproduce it anymore.

Arnab Chakraborty
  • 7,442
  • 9
  • 46
  • 69