Запуск функции обратного вызова в асинхронном режиме - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь понять, как запускать функции обратного вызова в асинхронном консольном приложении.Мой код приложения базовой консоли выглядит следующим образом:

    using Nito.AsyncEx;

    static void Main(string[] args)
    {
        AsyncContext.Run(() => MainAsync());
    }

    static async Task MainAsync()
    {


    }

Метод, который я хочу запустить в асинхронном режиме, является следующим из API веб-сокета:

using ExchangeSharp;

public static void Main(string[] args)
{
    // create a web socket connection to Binance. Note you can Dispose the socket anytime to shut it down.
    // the web socket will handle disconnects and attempt to re-connect automatically.
    ExchangeBinanceAPI b = new ExchangeBinanceAPI();
    using (var socket = b.GetTickersWebSocket((tickers) =>
    {
        Console.WriteLine("{0} tickers, first: {1}", tickers.Count, tickers.First());
    }))
    {
        Console.WriteLine("Press ENTER to shutdown.");
        Console.ReadLine();
    }
}

Вышеприведенный код предназначензаблокировать консольное приложение и подписаться на событие, которое получает данные, и сделать что-то с полученными данными.

Что я хочу сделать, это запустить вышеупомянутое в отдельном потоке или в асинхронном режиме, чтобы я мог продолжитьс моим кодом в функции MainAsync ().

Мой опыт работы с C # ограничен.Буду признателен за любую помощь!

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Асинхронный метод не блокирует поток вызывающего, если вы используете его напрямую, вы можете просто вызвать его где-нибудь до Consolo.ReadLine(), а затем использовать возвращенный Task для обработки результата, если вам нужно.

public static void Main(string[] args)
{
    // Would not block the thread.
    Task t = MainAsync();

    // Only if you need. Would not block the thread too.
    t.ContinueWith(()=> { code block that will run after MainAsync() });

    // create a web socket connection to Binance. Note you can Dispose the socket anytime to shut it down.
    // the web socket will handle disconnects and attempt to re-connect automatically.
    ExchangeBinanceAPI b = new ExchangeBinanceAPI();
    using (var socket = b.GetTickersWebSocket((tickers) =>
    {
        Console.WriteLine("{0} tickers, first: {1}", tickers.Count, tickers.First());
    }))
    {
        Console.WriteLine("Press ENTER to shutdown.");
        Console.ReadLine();
    }
}
0 голосов
/ 23 мая 2018

Согласно исходному коду GetTickersWebSocket не является блокирующим вызовом.

Единственный блокирующий вызов, который вы отправили, - Console.ReadLine.ExchangeBinanceAPI имеет свою собственную асинхронность на основе обратного вызова, поэтому просто отбросьте Console.ReadLine или поместите перед ней больше кода:

static async Task MainAsync()
{
    ExchangeBinanceAPI b = new ExchangeBinanceAPI();
    using (var socket = b.GetTickersWebSocket((tickers) =>
    {
        Console.WriteLine("{0} tickers, first: {1}", tickers.Count, tickers.First());
    }))
    {
        // code continues here

        Console.WriteLine("Press ENTER to shutdown.");
        Console.ReadLine();
    }
}

В качестве примечания.

Я не знаком с этим проектом , но исходный код показывает асинхронность бедняка внутри WebSocketWrapper:

Task.Factory.StartNew(ListenWorkerThread)

// inside ListenWorkerThread
_ws.ConnectAsync(_uri, CancellationToken.None).GetAwaiter().GetResult();
result = _ws.ReceiveAsync(receiveBuffer, _cancellationToken).GetAwaiter().GetResult();

и т. Д.

Тамэто попытки вызвать асинхронный код синхронным способом.
Вместо этого, по крайней мере, ListenWorkerThread должен быть преобразован в метод async, и его определенно нельзя вызывать с помощью Task.Factory.StartNew.

Iотправил бы запрос на переписывание кода в истинно асинхронном режиме, если бы мне пришлось использовать этот проект.

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