Как справиться с асинхронным / ожидающим использованием в библиотеке, вызываемой извне. Net? - PullRequest
0 голосов
/ 29 января 2020

Я новичок в этой области C# и, честно говоря, изо всех сил пытаюсь уловить парадигму. Кажется, я не одинок ( Где асин c и ждет конца? Путаница , http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html)

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

class MyServer
{
 void StartServerRunningAsync(Callback callback)
 {
  this.callback = callback; //calls back into unmanaged via 'magic' COM interop each time a TCP client posts interesting data
  StartRunningThread(); //this creates a thread to run the server and returns 
 }
 void StartRunningThread()
 {
  new Thread(new ThreadStart(Run)).Start();
 }
 void Run()
 {
  //do standard TCP async stuff treating `Run` like a local `Main`
 }
}

Эта библиотека будет использоваться из неуправляемого приложения C ++ (в частности, через COM), которое запускает сервер в фоновом режиме. Так что я не думаю, что StartServerRunning может / должно быть async, но это означает, что я застрял / запутался, как вообще использовать async / await, поскольку он распространяется по всему вашему стеку на основе ссылок. над.

Это действительно проблема или я неправильно понял что-то фундаментальное? Как TPL может быть заключен в капсулу таким образом?

1 Ответ

0 голосов
/ 29 января 2020

На самом деле, использование async / await делает вещи намного проще.

class MyServer
{
 // notice async void here instead of async Task
 async void StartServerRunning(Callback callback)
  {
   await StartRunningThreadAsync(); // start server asynchronously
   callback();
  }
}

С точки зрения внешнего наблюдателя, StartServerRunning завершается немедленно, когда встречает первое ожидание. Но в фоновом режиме, метод все еще "работает". И когда StartRunningThreadAsync заканчивается, вызывается callback. Это не очень хорошая практика, когда используется внутри кода C#, но я не вижу ничего плохого, когда задействовано взаимодействие C.

Я бы также рекомендовал реализовать обработку исключений, чтобы исключение может выйти за пределы этого метода. Нравится:

class MyServer
{
 async void StartServerRunning(Callback callback)
  {
   bool wasError = false;
   try{
     await StartRunningThreadAsync(); // start server asynchronously
   }catch(Exception ex)
   {
     // log exception
     wasError = true;
   }
   callback(wasError);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...