Сохраняется ли блокировка до тех пор, пока не будут вызваны анонимные делегаты и/или пока они не запущены?

Если бы у меня был:

lock(myLockObject)
{
    mySharedBuffer.Modfiy();
    something.BeginDoStuff(new Action(delegate()
        {
            mySharedBuffer.Modify();
        }));
}

И обратный вызов, предоставляемый BeginDoStuff (), вызван обратно в другой поток - заблокирован ли он/повторно получен, когда обратный вызов в конечном итоге запущен? (Я предполагаю, что блокировка потеряна, и мне нужно снова заблокировать, но не могу найти документацию, говорящую так)

1
добавлено
Просмотры: 2
nl ja de

4 ответы

является блокировкой, удерживаемой/повторно полученной, когда вызов обратного вызова в конечном счете запущен?

Нет - волшебства не происходит!

BeginXXX returns immediately and control drops out of the lock block and the lock is released.

Если вы хотите снова получить блокировку в обратном вызове, вам понадобится другой блок lock .

Как и при всех блокировках, это означает, что вы должны оставить объект mySharedBuffer в состоянии consiteent, когда блокировка будет выпущена. Кроме того, этот объект может быть изменен другим потоком между временем освобождения блокировки после BeginXXX и временем, когда ваш обратный вызов снова получит блокировку.


Если реализация BeginXXX может выполнять обратный вызов синхронно, то столбец будет похож на обычный последовательный код, и блокировка все равно будет сохранена. В этом случае, если вы попытаетесь снова получить блокировку в обратном вызове, она будет получена немедленно, потому что Monitor позволяет рекурсивные блокировки в одном потоке.

2
добавлено
из любопытства: что, если обратный вызов завершается синхронно в той же теме?
добавлено автор markmnl, источник
Я добавил этот случай к моему ответу.
добавлено автор Nicholas Butler, источник

является блокировкой, удерживаемой/повторно полученной, когда вызов обратного вызова в конечном счете запущен?

Нет - волшебства не происходит!

BeginXXX returns immediately and control drops out of the lock block and the lock is released.

Если вы хотите снова получить блокировку в обратном вызове, вам понадобится другой блок lock .

Как и при всех блокировках, это означает, что вы должны оставить объект mySharedBuffer в состоянии consiteent, когда блокировка будет выпущена. Кроме того, этот объект может быть изменен другим потоком между временем освобождения блокировки после BeginXXX и временем, когда ваш обратный вызов снова получит блокировку.


Если реализация BeginXXX может выполнять обратный вызов синхронно, то столбец будет похож на обычный последовательный код, и блокировка все равно будет сохранена. В этом случае, если вы попытаетесь снова получить блокировку в обратном вызове, она будет получена немедленно, потому что Monitor позволяет рекурсивные блокировки в одном потоке.

2
добавлено
из любопытства: что, если обратный вызов завершается синхронно в той же теме?
добавлено автор markmnl, источник
Я добавил этот случай к моему ответу.
добавлено автор Nicholas Butler, источник

Нет. Анонимный делегат не относится к области lock .

Обычно метод BeginXXX выполняет асинхронную операцию и немедленно возвращается. Соответствующий метод EndXXX также ждет завершения операции.

Если вы хотите заблокировать анонимного делегата, вам нужно использовать вложенную блокировку.

lock(myLockObject)
{
    mySharedBuffer.Modfiy();
    something.BeginDoStuff(new Action(delegate()
        {
            lock (myLockObject)//nested locking here
            {
               mySharedBuffer.Modify();
            }
       }));
}
0
добавлено

Нет. Анонимный делегат не относится к области lock .

Обычно метод BeginXXX выполняет асинхронную операцию и немедленно возвращается. Соответствующий метод EndXXX также ждет завершения операции.

Если вы хотите заблокировать анонимного делегата, вам нужно использовать вложенную блокировку.

lock(myLockObject)
{
    mySharedBuffer.Modfiy();
    something.BeginDoStuff(new Action(delegate()
        {
            lock (myLockObject)//nested locking here
            {
               mySharedBuffer.Modify();
            }
       }));
}
0
добавлено