AsyncLocal, держащий стек - казалось бы, твердый код выдает «Stack empty».Почему? - PullRequest
8 голосов
/ 25 сентября 2019

Я знаю , что AsyncLocal сложно.Однако я даже не уверен на 100%, что в этом виноват.Я не могу понять, как приведенный ниже код не является "воздухонепроницаемым".

private readonly AsyncLocal<Stack<int>> _myStack = new AsyncLocal<Stack<int>>();

private void MyMethod()
{
    var myStack = _myStack.Value ?? (_myStack.Value = new Stack<int>());
    myStack.Push(42);
    try
    {
        // code here, which may recursively call the same function again.
        // all single-threaded without any async calls, though
    }
    finally
    {
        myStack.Pop(); // this occasionally throws "Stack empty"
    }
}

Когда генерируется исключение, стек вызовов в этом методе имеет только одну глубину.

Других ссылок на _myStack нет, и myStack (локальная переменная) не передается и не используется где-либо еще.

Где нарушается мое понимание?Независимо от AsyncLocal, я хватаю объект Stack<>, подталкиваю что-то к нему - и, что бы ни случилось, высовывается только один раз в finally.

Нет других исключений -стек совсем не глубокий (в данном случае 1 или 2, может быть, 3 уровня).Там нет неуправляемого кода.

У меня нет минимального репро, и кажется, что это происходит случайно.Вот почему AsyncLocal был введен в первую очередь - в случае, если два потока были вовлечены и повредили внутреннее состояние Stack, возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...