Когда использовать поток блокировки в C #?

У меня есть сервер, который обрабатывает несколько входящих соединений через сокеты и создает 2 разных потока, которые хранят данные в формате XML.

Я использовал оператор lock для обеспечения безопасности потоков почти в каждом обработчике событий, вызываемом асинхронно, и в двух потоках в разных частях кода. К сожалению, при таком подходе мое приложение значительно замедляется.

Я пытался вообще не использовать блокировку , сервер работает очень быстро, даже объем хранилища файлов, кажется, увеличивается; но программа вылетает по непонятным причинам через 30 секунд - 1 минуту. работы.

Итак. Я подумал, что лучше всего использовать меньше блокировок или использовать их только там, где это строго необходимо.Таким образом, у меня есть 2 вопроса:

  1. Требуется ли блокировка, когда я пишу только в общедоступные переменные (списки C #) или даже когда я читаю из них?

  2. Требуется ли блокировка только в асинхронных потоках, созданных с помощью обработчик сокетов или в других местах тоже?

Кто-нибудь может дать мне несколько практических советов о том, как работать. На этот раз я не буду публиковать весь код. Нет смысла размещать около 2500 строк кода.

27
задан Claudio Ferraro 28 August 2013 в 03:43
поделиться

3 ответа

Нужна ли блокировка, когда я пишу только в общедоступные переменные (списки C #) или даже когда читаю из них?

Да (даже когда вы читаете).

Требуется ли блокировка только в асинхронных потоках, созданных обработчиком сокетов или в других местах?

Да. Везде, где код обращается к разделу кода, который является общим, всегда блокируйте.


Похоже, вы не блокируете отдельных объектов, но блокируете одну вещь для всех ситуаций блокировки.

Если это так, вставьте интеллектуальные дискретные блокировки, создав индивидуальные уникальные объекты, которые связывают и блокируют только определенные разделы одновременно, которые не мешают другим потокам в других разделах.

Вот пример:

// This class simulates the use of two different thread safe resources and how to lock them
// for thread safety but not block other threads getting different resources.
public class SmartLocking
{
    private string StrResource1 { get; set; }
    private string StrResource2 { get; set; }

    private object _Lock1 = new object();
    private object _Lock2 = new object();

    public void DoWorkOn1( string change )
    {
        lock (_Lock1)
        {
            _Resource1 = change;
        }
    }

    public void DoWorkOn2( string change2 )
    {
        lock (_Lock2)
        {
            _Resource2 = change2;
        }
    }
}
33
ответ дан 28 November 2019 в 04:02
поделиться

Причина, по которой вам нужно заблокировать во время чтения:

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

Надеюсь, это поможет,

1
ответ дан 28 November 2019 в 04:02
поделиться

В основном на это можно ответить довольно просто:

Вам нужно заблокировать все вещи, к которым обращаются разные потоки. Это действительно не имеет значения, если речь идет о чтении или письме. Если вы читаете, а другой поток перезаписывает данные одновременно, считанные данные могут стать недействительными, и вы, возможно, выполняете недопустимые операции.

0
ответ дан 28 November 2019 в 04:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: