Loran
Loran

Reputation: 842

Async inside Loop

I try to test this structure but it never works.
I believe I have misunderstood it or lack knowledge in concurrency.

Please light me to the correct direction.

I call a save method but this never saves.

My code :

public async Task<MyObject> GetMyObject_ById(int id)
{
    var responseDto = await this.RestApi.QueryMyObject_ById(id).ConfigureAwait(false);

    if (responseDto != null)
    {
       return this.mapper.Map<MyObject>(responseDto);
    }
    else
    {
       return null;
    }
}

public async Task<MyObject> UpdateMyObject(int id, MyObject updatevalue)
{
    var dto = this.mapper.Map<MyObjectDto>(updatevalue);

    var updateinfo = await this.RestApi.Update(id, dto).ConfigureAwait(false);

    return this.mapper.Map<MyObject>(updateinfo);
}


private void Save()
{    
    foreach (MyObject pb in this.ListToSave)
    {
         this.SaveValue(pb.Id, pb.Status));
    }
}

private async Task<MyObject> SaveValue(int id,string status)
{
     var info = this.GetMyObject_ById(id).Result;

     info.Status = status;

     return await this.RestApi.UpdateMyObject(id, info).ConfigureAwait(false);
}

Upvotes: 0

Views: 179

Answers (1)

JonasH
JonasH

Reputation: 36341

Just to summarize the comments. You should replace this.GetMyObject_ById(id).Result; with await this.GetMyObject_ById(id); to avoid blocking. .Result and .Wait() should be avoided since they can cause deadlocks.

You probably want your save method to look like:

private async void Save()
{
    try
    {    
         foreach (MyObject pb in this.ListToSave)
        {
             await this.SaveValue(pb.Id, pb.Status));
        }
     }
     catch(Exception e){ 
     // handle exception
     }
}

or

private async Task Save()
{    
    foreach (MyObject pb in this.ListToSave)
    {
         await this.SaveValue(pb.Id, pb.Status));
    }
}

When using async methods you should always have some way to handle the result, even if the result might be an exception. This also executes each save call after the previous has completed, this is typically not a bad idea since it helps avoid threading issues.

Upvotes: 3

Related Questions