Может ли кто-нибудь сказать мне, что лучший способ/правильный способ сделать это?
Я также использую WPF, а не консоль или ASP.NET.Понимание огня и забывание при использовании бесконечных циклов
Использование прослушивателя для приема клиентов и выделения нового «потока» для каждого клиента, который обрабатывает все операции ввода-вывода и исключения для этого клиента.
Способ 1: Огонь и забудьте, и просто выбросьте его в переменную, чтобы избавиться от предупреждения.
public static async Task Start(CancellationToken token)
{
m_server = TcpListener.Create(33777);
m_server.Start();
running = true;
clientCount = 0;
// TODO: Add try... catch
while (!token.IsCancellationRequested)
{
var client = await m_server.AcceptTcpClientAsync().ConfigureAwait(false);
Client c = new Client(client);
var _ = HandleClientAsync(c);
}
}
Вот код клиента Handler:
public static async Task HandleClientAsync(Client c)
{
// TODO: add try...catch
while (c.connected)
{
string data = await c.reader.ReadLineAsync();
// Now we will parse the data and update variables accordingly
// Just Regex and some parsing that updates variables
ParseAndUpdate(data);
}
}
Метод 2: То же самое ... но с Task.Run()
var _ = Task.Run(() => HandleClientAsync());
Метод 3: промежуточный, не асинхронном (сомните, что это хорошо. Должно быть Async полностью)
Но это, по крайней мере, избавляется от неряшливой линии, не используя переменную трюк, которая кажется грязной.
while (!token.IsCancellationRequested)
{
var client = await m_server.AcceptTcpClientAsync().ConfigureAwait(false);
Client c = new Client(client);
NonAsync(c);
}
public static void NonAsync(VClient vc)
{
Task.Run(() => HandleClientAsync(vc));
}
Метод 4: Сделайте HandleClientAsync Асинхронной пустоты вместо асинхронной Task (очень плохо)
public static async Task HandleClientAsync(Client c)
// Would change to
public static async Void HandleClientAsync(Client c)
Вопросов:
- ли лучше использовать
Task.Run()
при выполнении огонь и забыть задачу? - Приходится ли вам использовать трюк
var _ = FireAndForget()
, чтобы сделать огонь и забыть? Я мог просто игнорировать предупреждение, но что-то не так. - Если бы я хотел обновить свой пользовательский интерфейс от клиента, как бы я это сделал? Я бы просто использовал диспетчера?
Спасибо, ребята
Вы не должны использовать поток для обработки ввода/O-связанные задачи, IOCP не требуют потоков. Скручивание нитки - это отходы. – MickyD
@MickyD, то как бы получить данные от клиента 3, если клиент 1 и 2 простаивают? Если я ожидаю данные от своих потоков, то я «блокирую», пока не получу эти данные. Если я использую 'WhenAll()', то я не могу получить данные от клиента 3 более одного раза. Однако я не вижу другого варианта. –
Что заставляет вас думать, что 'await' является _" блокировкой "_? – MickyD