Search code examples
c#async-awaitconditional-operator

How to use await in a ternary operator in C#?


With this code the call to SoftUpdateAsync and UpdateAsync seems not awaited and I got an error of deadlock transaction.

_ = await _tabRepository.IsReferencedFromAnotherTableAsync(entity.Id)
    ? _tabRepository.SoftUpdateAsync(entity)
    : _tabRepository.UpdateAsync(entity);

The function IsReferencedFromAnotherTableAsync return a bool, the UpdateAsync and the SoftUpdateAsync returning a Task.

But, If I wrote the code as

if (await _tabRepository.IsReferencedFromAnotherTableAsync(entity.Id))
    await _tabRepository.SoftUpdateAsync(entity);
else
    await _tabRepository.UpdateAsync(entity);

all seems to work correctly.

Can I use ternary operator instead of if then else ?

I tried with:

_ = await _countdownRepository.IsReferencedFromAnotherTableAsync(entity.Id)
    ? await _countdownRepository.SoftUpdateAsync(entity)
    : await _countdownRepository.UpdateAsync(entity);

and

await _countdownRepository.IsReferencedFromAnotherTableAsync(entity.Id)
    ? await _countdownRepository.SoftUpdateAsync(entity)
    : await _countdownRepository.UpdateAsync(entity);

Both result in errors:

First one is "A value of type void may not be assigned", the second one is "Only assignment, call, increment, decrement, and new object expressions can be used as a statement "


Solution

  • I strongly suspect you want:

    await (await _countdownRepository.IsReferencedFromAnotherTableAsync(entity.Id)
        ? _countdownRepository.SoftUpdateAsync(entity)
        : _countdownRepository.UpdateAsync(entity));
    

    Or to make it clearer what's going on:

    var task = await _tabRepository.IsReferencedFromAnotherTableAsync(entity.Id)
        ? _tabRepository.SoftUpdateAsync(entity)
        : _tabRepository.UpdateAsync(entity);
    await task;
    

    I strongly suspect the problem is that _tabRepository.SoftUpdateAsync(entity) (and the other branch) both return just Task - which when you await it, doesn't return anything. You can't have a conditional ?: expression where the two branches don't return anything. So you need to determine which task you want to await, then await it - which is what my two options above do.