Чтение отменяется перед удалением потока, но все же выбрасывает исключение [дубликат]

Отсутствует «extern» в объявлениях / определениях переменной const (только для C ++)

Для людей, прибывающих с C, может показаться неожиданным, что в C ++ глобальные переменные const имеют внутренние (или статические) связь. В C это не так, поскольку все глобальные переменные неявно extern (т.е. когда отсутствует ключевое слово static).

Пример:

// file1.cpp
const int test = 5;    // in C++ same as "static const int test = 5"
int test2 = 5;

// file2.cpp
extern const int test;
extern int test2;

void foo()
{
 int x = test;   // linker error in C++ , no error in C
 int y = test2;  // no problem
}

correct would использовать файл заголовка и включить его в file2.cpp и file1.cpp

extern const int test;
extern int test2;

. В качестве альтернативы можно было бы объявить переменную const в файле file1.cpp с явным extern

4
задан spender 21 November 2013 в 22:53
поделиться

1 ответ

Нет, NetworkStream не поддерживает отмену.

К сожалению, базовые API Win32 не всегда поддерживают отмену транзакции. Традиционно вы можете отменить все ввода / вывода для определенного дескриптора, но метод отмены одной операции ввода-вывода является довольно недавним. Большинство .NET BCL были написаны против XP API (или старше), который не включал CancelIoEx.

Stream связывает эту проблему с помощью «подделки» поддержки отмены (и асинхронного ввода / O тоже), даже если реализация не поддерживает его. «Поддельная» поддержка отмены просто проверяет токен сразу, а затем запускает регулярное асинхронное чтение, которое нельзя отменить. Вот что вы видите с NetworkStream.

С сокетами (и большинством типов Win32) традиционный подход заключается в том, чтобы закрыть дескриптор, если вы хотите прервать связь. Это приводит к сбою всех текущих операций (как чтения, так и записи). Технически это является нарушением безопасности потока BCL, как это описано в документе, но оно действительно работает.

cts.Token.Register(() => client.Close());
...
catch (ObjectDisposedException)

Если, с другой стороны, вы хотите обнаружить сценарий полуоткрытия (где ваша сторона читает, но другая сторона потеряла свое соединение), то лучшим решением является периодическая отправка данных. Я описываю это больше в своем блоге .

13
ответ дан Stephen Cleary 25 August 2018 в 01:20
поделиться