Using locks in an asynchronous method

I have some doubts as to whether the “library” method below will work, or, ultimately, a dead end.

I have an “old” object that needs to be protected, and “ locking ” seems to be the best tool, given that there are some reentrant calls to this resource (SomeSharedResource) throughout the “class”.

EDIT:

1.) Will the call “Calculate” actually block or the worst case block?

var finalResult = await Compute(3).ConfigureAwait(false); // will this block?

2.) How about the one who did this?

 var finalResult = Compute(3).Result; // will this block/deadlock?

3.) 2 Concurrent thread calls:

 var finalResult = await Compute(3).ConfigureAwait(false); // will this block?

This method:

private readonly object lockObject = new object();
private async Task<double> Compute(int input)
{
    double result;
    lock (lockObject) {
        result = SomeSharedResource(input);
    }

   return  await ComputeAsync(result).ConfigureAwait(false); // some other awaitable method

}
+4
source share
3 answers
  • Compute(int input) . lock (lockobject) . lockObject, , , .

  • , # 1. , , . ComputeAsync(), .Result

  • , # 1.

- . , , . , , ( : .Result , ).

, () . async - await ​​ .

+2

. - ", , ".

" lock ?", ( , SomeSharedResource(input) , ).

+2

1, 2 3 : ", , ". lock , , , .

, lock, .

, lock (await ), Compute() , lockObject.

lock , . , , , .

, , :

private async Task<double> DoSomething()
{
    return await Compute(0);
}

private readonly object lockObject = new object();
private async Task<double> Compute(int input)
{
    double result;
    lock (lockObject) {
        //This would be bad.
        result = await DoSomething();

        //So would this.  If you didn't wait inside the lock you wouldn't deadlock though.
        var t = DoSomething();
        result = t.Result;

        //This would be okay because it doesn't call back to Compute()
        using (var stream = File.OpenText("test.txt"))
        {
            var contents = await stream.ReadToEndAsync();
        }
    }

   return  await ComputeAsync(result).ConfigureAwait(false); // some other awaitable method

}
+1

Source: https://habr.com/ru/post/1611882/


All Articles