РЕДАКТИРОВАТЬ: Хорошо, у меня была проблема с одной из функций конкатенации строк, не имеет никакого отношения к потокам, но зная, что это не может быть проблемой с потоками, привело меня к ответу спасибо за ответ.
Я делаю простую программу чата tcp / ip для отработки потоков и tcp / ip. Я использовал асинхронные методы, но у меня была проблема с параллелизмом, поэтому я перешел к потокам и методам блокировки (не асинхронным). У меня есть две частные переменные, определенные в классе, а не статические:
string amessage = string.Empty;
int MessageLength;
и нить
private Thread BeginRead;
Хорошо, поэтому я вызываю функцию Listen ONCE при запуске клиента:
public virtual void Listen(int byteLength)
{
var state = new StateObject {Buffer = new byte[byteLength]};
BeginRead = new Thread(ReadThread);
BeginRead.Start(state);
}
и, наконец, функция для получения команд и их обработки, я собираюсь сократить их, потому что они действительно длинные:
private void ReadThread(object objectState)
{
var state = (StateObject)objectState;
int byteLength = state.Buffer.Length;
while (true)
{
var buffer = new byte[byteLength];
int len = MySocket.Receive(buffer);
if (len <= 0) return;
string content = Encoding.ASCII.GetString(buffer, 0, len);
amessage += cleanMessage.Substring(0, MessageLength);
if (OnRead != null)
{
var e = new CommandEventArgs(amessage);
OnRead(this, e);
}
}
}
Теперь, насколько я понимаю, только один поток за раз будет вводить BeginRead
, я звоню Receive
, он блокируется до тех пор, пока я не получу данные, а затем обработаю их. Проблема: переменная amessage
изменит свое значение между операторами, которые вообще не касаются или не изменяют переменную, например, в нижней части функции по адресу: if (OnRead != null)
«amessage» будет равно «asdf» и в if (OnRead != null)
"amessage" будет равен qwert. Насколько я понимаю, это указывает на то, что другой поток изменяет значение / работает асинхронно. Я только порождаю один поток для получения, а функция Receive блокирует, как может быть два потока в этой функции, и если есть только один поток, как значение amessage изменяется между операторами, которые не влияют на его значение. В качестве примечания, извините за спам на сайте с этими вопросами, но я только знакомлюсь с этой многопоточной историей, и это заставляет меня хотеть потягивать цианид.
Заранее спасибо.
EDIT:
Вот мой код, который вызывает метод Listen в клиенте:
public void ConnectClient(string ip,int port)
{
client.Connect(ip,port);
client.Listen(5);
}
и на сервере:
private void Accept(IAsyncResult result)
{
var client = new AbstractClient(MySocket.EndAccept(result));
var e = new CommandEventArgs(client, null);
Clients.Add(client);
client.Listen(5);
if (OnClientAdded != null)
{
var target = (Control) OnClientAdded.Target;
if (target != null && target.InvokeRequired)
target.Invoke(OnClientAdded, this, e);
else
OnClientAdded(this, e);
}
client.OnRead += OnRead;
MySocket.BeginAccept(new AsyncCallback(Accept), null);
}
Весь этот код находится в классе с именем AbstractClient. Клиент наследует абстрактный клиент, и когда сервер принимает сокет, который он создает, он создает собственный локальный AbstractClient, в этом случае оба модуля обращаются к функциям, описанным выше, однако это разные экземпляры, и я не мог представить себе, что потоки из разных экземпляров объединяются, тем более что ни одна переменная не является статичный.