Выполнение вложенных асинхронных функций на разных этапах - PullRequest
0 голосов
/ 11 сентября 2018

Если у меня есть:

server.Start(socket =>
        {
            socket.doStuff() = async binary =>
            {
                 ...
                 await Method1();
                 ...
                 await Method2();
            };
        }

и задача doStuff() вызывается очень часто (каждые 20 мс), как правильно выполнить Method1() при первом doStuff() вызове, а затем Method2() при всех последующих doStuff() звонки? Я попытался использовать логическое и если утверждения, такие, что:

server.Start(socket =>
        {
            socket.doStuff() = async binary =>
            {
                if(firstCall == true)
                {
                   await Method1();
                   firstCall = false;
                }

                else
                await Method2();
            };
        }

Однако я обнаружил, что этот код не работает, потому что await Method1();, по-видимому, вызывался более одного раза. Таким образом, казалось, что когда вызывается следующий doStuff(), Method1() еще не ожидался от первого doStuff(), поскольку он все еще выполнялся, и, следовательно, firstCall все еще true, в результате чего Method1() было позвонил снова. Можно ли сделать это без кучи логических значений? Как мне этого добиться?

EDIT

Чтобы уточнить ... .doStuff() вызывается каждый раз, когда websocket получает двоичное сообщение (которое происходит каждые 20 мс). Я не могу это контролировать, поэтому, работая в этих пределах: я хочу вызвать Method1() only ONCE и хочу, чтобы он вызывался в самом первом сообщении (при первом вызове .doStuff()). Каждый раз, когда вызывается .doStuff(), я хочу, чтобы вызывался Method2() и NOT Method1(). Я также хотел бы убедиться, что после вызова Method1() он завершает до вызова Method2(). Если я потеряю здесь некоторые двоичные данные, это не проблема.

1 Ответ

0 голосов
/ 11 сентября 2018

Как насчет этого:

var beforeFirst = true;

server.Start(socket =>
{
    socket.doStuff = async () =>
    {
        if (beforeFirst) {
            beforeFirst = false;
            await Method1();
            socket.doStuff = Method2;
        }
    };
}
  • Когда doStuff () вызывается в первый раз, он запускается Method1().
  • Когда doStuff () вызывается при Method1(), он ничего не делает.
  • Когда Method1() закончен, он заменяет doStuff() на Method2().

Единственная плохая вещь заключается в том, что установка и чтение beforeFirst, возможно, должны выполняться каким-то Interlocked методом, чтобы избежать состояния гонки в этом месте.

...