Избегать повторяющихся звонков на рутину из нескольких потоков в выигрышной форме? - PullRequest
0 голосов
/ 19 октября 2011

У меня есть переменная частного объекта в форме Windows, которая выполняет соединение через сокет tcp / IP и поддерживает соединение открытым.

При form_load этот объект инициализируется, и форма имеет 15-20 непрерывно работающих потоковвнутри него, которые получают доступ к этому объекту.Существуют сценарии, в которых соединение Tcp / Ip может быть потеряно.Поэтому всякий раз, когда я обнаруживаю, что соединение потеряно, я вызываю метод ReconnectToSocket () в потоке.Я выполняю приведенный ниже код, чтобы гарантировать, что метод ReconnectToSocket () вызывается только один раз с использованием свойства _ReconnectingSocket .Но после проверки файлов текстового журнала я обнаружил, что этот метод вызывается внутри каждого подпотока.

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

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

    bool _bReconnectingSocket = false;//To check if it is currently reconnecting
    readonly object lock_reconnectSocket = new object();
    private bool _ReconnectingSocket
    {
        get
        {
            lock (lock_reconnectSocket)
            {
                return this._bReconnectingSocket;
            }
        }
        set
        {
            lock (lock_reconnectSocket)
            {
                this._bReconnectingSocket = value;
            }
        }
    }


    private void ReconnectToSocket()
    {
        if (!this._ReconnectingSocket)
        {
            this._ReconnectingSocket = true;

            //Each sub thread checks for this variable while looping and exits from the infinite loop
            this._Stop = true;

            //Join all the Sub Threads Before Reconnecting
            foreach (SocketThread thrd in this._subThreadCol)
            {
                try
                {
                    this._objLog.WriteInfo(string.Format("Joining Subthread - {0} for Reconnecting.", thrd.ThrdID));
                    thrd.Join();
                }
                catch { }
            }

            this.ConnectSocket();

            this._ReconnectingSocket = false;
            this._Stop = false;
        }
    }

Ответы [ 2 ]

1 голос
/ 19 октября 2011

Привет объект, против которого вы блокируете, должен быть статическим закрытым классом, а не членом экземпляра.Одна вещь, в которой я не уверен, это то, почему вы разделяете одно и то же соединение между потоками вместо того, чтобы каждый поток открывал, использовал и сразу закрывал свой собственный, как мы это сделали бы с SqlConnection.

1 голос
/ 19 октября 2011

Попробуй написать что-нибудь подобное в своем классе. Ваша процедура все еще может вызываться несколько раз, но ее фактическое тело будет выполняться только один раз за раз, если поле reconnected имеет значение false.

bool reconnected = false;
object lockObject = new object();

void ReconnectToSocket()
{
  lock(lockObject)
  {
    if(!reconnected) { /*do stuff*/; reconnected = true; }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...