Gaurav Bhardwaj
Gaurav Bhardwaj

Reputation: 87

Unable to write to my container using CreateItemAsync using Cosmos 3.3 sdk

I am using Cosmos 3.3 sdk and below is the code to write to my container.

 public void WriteErrorLogs(Error entity, string collectionName)
        {
            try
            {
                Container container = cosmosclient.GetContainer(databaseName, collectionName);
                entity.LogID = Guid.NewGuid().ToString();          
                container.CreateItemAsync<Error>(entity, new PartitionKey(entity.LogID));
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

The container in cosmos look like this having partition key as id

enter image description here

the Error class is like this

  public class Error
    {
        [JsonProperty(PropertyName = "id")]
        public string LogID { get; set; }

        public System.DateTime DateStamp { get; set; }
        public string EID { get; set; }
        public string Message { get; set; }
        public string StackTrace { get; set; }
        public string InnerException { get; set; }

I defined partition key to be the LogID which is a guid.The method needs to be synchronous due to the code constraint. Not sure where I am wrong but while debugging always getting" container error CS0103: The name 'container' does not exist in the current context" and logs are not getting created.Any help would be really appretiated,Thanks

Upvotes: 2

Views: 4976

Answers (2)

Gaurav Bhardwaj
Gaurav Bhardwaj

Reputation: 87

I found the issue.It was a threading issue as told by Matias.I explicitly run the task as Task.Run (async..functioncall).wait() and then in the function call defined createItemasync as a sync call.

Upvotes: -1

Matias Quaranta
Matias Quaranta

Reputation: 15603

You are doing a fire-and-forget, the CreateItemAsync is a Task, an async operation, and you are not awaiting it.

public async Task WriteErrorLogs(Error entity, string collectionName)
{
    try
    {
        Container container = cosmosclient.GetContainer(databaseName, collectionName);
        entity.LogID = Guid.NewGuid().ToString();          
        await container.CreateItemAsync<Error>(entity, new PartitionKey(entity.LogID));
    }
    catch (Exception ex)
    {
        throw ex;
    }

}

And anywhere you call WriteErrorLogs you need to await it too.

For example:

await WriteErrorLogs(entity, "myerrorcollection")

During your build process, there might be Warnings pointing at this specific issue.

EDIT: Based on OP comment, adding how to force the operation to be sync, but this is not recommended, you might potentially end with deadlocks, see https://stackoverflow.com/a/24298425/5641598

public void WriteErrorLogs(Error entity, string collectionName)
{
    try
    {
        Container container = cosmosclient.GetContainer(databaseName, collectionName);
        entity.LogID = Guid.NewGuid().ToString();          
        container.CreateItemAsync<Error>(entity, new PartitionKey(entity.LogID)).GetAwaiter().GetResult();
        // or ItemResponse<Error> response = container.CreateItemAsync<Error>(entity, new PartitionKey(entity.LogID)).Result;
        // or container.CreateItemAsync<Error>(entity, new PartitionKey(entity.LogID)).Wait();
    }
    catch (Exception ex)
    {
        throw ex;
    }

}

Upvotes: 3

Related Questions