Как удовлетворить требование синхронизации вызова WriteAsync() в потоке gRPC (C#) [дубликат] ⇐ C#
Как удовлетворить требование синхронизации вызова WriteAsync() в потоке gRPC (C#) [дубликат]
На моем сервере gRPC (C# на .NET 7) открыто несколько подписок на потоковую передачу (несколько клиентов, каждый из которых имеет несколько подписок). Каждый из них использует свой конкретный экземпляр потока IServerStreamWriter, который поступил с запросом на подписку. Все в порядке.
При определенных условиях (опуская подробности здесь) случается, что WriteAsync() в таком потоке вызывается одновременно из разных контекстов потока. Это может вызвать исключение с сообщением «Невозможно записать сообщение, поскольку выполняется предыдущая запись». Очевидно, что WriteAsync() не является потокобезопасным и обнаруживается «злоупотребление».
Я пытался синхронизировать доступ к экземпляру потока с помощью Monitor, поскольку lock() нельзя использовать с await (без исключения обработка, которая включает в себя другой Monitor.Exit()):
Monitor.Enter(поток); дождитесь потока.WriteAsync(данные); Monitor.Exit(поток); Тем не менее, я получаю упомянутую ошибку при более высокой нагрузке (конечно, это повышает вероятность этого).
Итак, как правильно синхронизировать доступ/избежать этой ошибки?
Избежать параллелизма на более высоком уровне возможно, но это гораздо сложнее, подвержено ошибкам и неэффективно. Поскольку параллельные ситуации встречаются довольно редко, оно того не стоит.
На моем сервере gRPC (C# на .NET 7) открыто несколько подписок на потоковую передачу (несколько клиентов, каждый из которых имеет несколько подписок). Каждый из них использует свой конкретный экземпляр потока IServerStreamWriter, который поступил с запросом на подписку. Все в порядке.
При определенных условиях (опуская подробности здесь) случается, что WriteAsync() в таком потоке вызывается одновременно из разных контекстов потока. Это может вызвать исключение с сообщением «Невозможно записать сообщение, поскольку выполняется предыдущая запись». Очевидно, что WriteAsync() не является потокобезопасным и обнаруживается «злоупотребление».
Я пытался синхронизировать доступ к экземпляру потока с помощью Monitor, поскольку lock() нельзя использовать с await (без исключения обработка, которая включает в себя другой Monitor.Exit()):
Monitor.Enter(поток); дождитесь потока.WriteAsync(данные); Monitor.Exit(поток); Тем не менее, я получаю упомянутую ошибку при более высокой нагрузке (конечно, это повышает вероятность этого).
Итак, как правильно синхронизировать доступ/избежать этой ошибки?
Избежать параллелизма на более высоком уровне возможно, но это гораздо сложнее, подвержено ошибкам и неэффективно. Поскольку параллельные ситуации встречаются довольно редко, оно того не стоит.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Почему это происходит намного медленнее, если я использую ReadAsync/WriteAsync?
Anonymous » » в форуме C# - 0 Ответы
- 11 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Исключение gRPC: io.grpc.StatusRuntimeException: UNAVAILABLE: недоступен
Anonymous » » в форуме JAVA - 0 Ответы
- 144 Просмотры
-
Последнее сообщение Anonymous
-