Вопрос скорее архитектурный.
Есть сервер(TcpListener), который в отдельном потоке принимает подключения. При подключении нового пользователя, в главной форме должна создаваться панелька с некоторыми контроллерами. Но есть проблема, создать элемент правления в форме нельзя из другого потока. Как это разрешить?
Пробовал Invoke, вылезает проблема для отдельного вопроса о синхронизации общих блоков памяти для различных потоков.
Контроллер сцен:
пока затупил на первой
public GameMaster(ref Form mainform)
{
this.mainform = mainform;
clients = new List<ConnectedEntity>();
components = new List<IBaseScene>
{
new NetBehaviourScene(CreateEntity)
};
}
void CreateEntity(TcpClient tcpclient)
{
ConnectedEntity client = new ConnectedEntity(ref mainform, ref tcpclient);
clients.Add(client);
}
Класс, хранящий поток клиента и его панельку:
public ConnectedEntity(ref Form mainform, ref TcpClient client)
{
this.client = client;
//int.Parse(Read().Substring(6, 1)) - seatID, который присылает клиент при подключении
gui = new Pretender(int.Parse(Read().Substring(6, 1)), ref mainform, (object sender, EventArgs e) => {
isCookieEaten = !isCookieEaten;
});
}
Сервер:
public FFServer(ref bool isConnectionAllowed, Action<TcpClient> ConnectedCallback)
{
port = 9850;
this.isConnectionAllowed = isConnectionAllowed;
this.ConnectedCallback = ConnectedCallback;
listener = new TcpListener(IPAddress.Any, port);
}
public void Update()
{
if (isConnectionAllowed)
{
listener.BeginAcceptTcpClient((IAsyncResult ar) =>
{
ConnectedCallback(listener.EndAcceptTcpClient(ar));
}, listener);
}
}
Создание панельки:
public Pretender(int seatID, ref Form mainform, Action<object, EventArgs> CookieCheckCallback)
{
this.mainform = mainform;
//точка первой панель относительно основной формы
panelStartPoint = new System.Drawing.Point(341, 12);
//расчёт окончательной точки панели (нечётные слева, чётные справа)
if (seatID % 2 != 0)
{
panelStartPoint = new System.Drawing.Point(panelStartPoint.X,
panelStartPoint.Y + yPanelOffset * (seatID / 2));
} else
{
panelStartPoint = new System.Drawing.Point(panelStartPoint.X + xPanelOffset,
panelStartPoint.Y + yPanelOffset * (seatID / 2));
}
this.pPretender = new System.Windows.Forms.Panel();
this.cbIsInGame = new System.Windows.Forms.CheckBox();
this.cbEatCookie = new System.Windows.Forms.CheckBox();
this.lSeatID = new System.Windows.Forms.Label();
this.lAnswer = new System.Windows.Forms.Label();
this.tbPretenderName = new System.Windows.Forms.TextBox();
pPretender.SuspendLayout();
this.lAnswer.AutoSize = true;
this.lAnswer.Location = new System.Drawing.Point(70, 159);
this.lAnswer.Name = "lAnswer";
this.lAnswer.Size = new System.Drawing.Size(18, 20);
this.lAnswer.TabIndex = 2;
this.lAnswer.Text = "?";
this.tbPretenderName.Location = new System.Drawing.Point(3, 32);
this.tbPretenderName.Name = "tbPlayerName";
this.tbPretenderName.Size = new System.Drawing.Size(271, 26);
this.lSeatID.AutoSize = true;
this.lSeatID.Location = new System.Drawing.Point(70, 96);
this.lSeatID.Name = "lSeatID";
this.lSeatID.Size = new System.Drawing.Size(18, 20);
this.lSeatID.Text = seatID.ToString();
this.cbEatCookie.AutoSize = true;
this.cbEatCookie.Checked = false;
this.cbEatCookie.CheckState = System.Windows.Forms.CheckState.Unchecked;
this.cbEatCookie.Location = new System.Drawing.Point(196, 64);
this.cbEatCookie.Name = "cbEatCookie";
this.cbEatCookie.Size = new System.Drawing.Size(77, 24);
this.cbEatCookie.Text = "Печенька";
this.cbEatCookie.UseVisualStyleBackColor = true;
this.cbEatCookie.Enabled = false;
this.cbEatCookie.CheckedChanged += new System.EventHandler(CookieCheckCallback);
this.cbIsInGame.AutoSize = true;
this.cbIsInGame.Checked = true;
this.cbIsInGame.CheckState = System.Windows.Forms.CheckState.Checked;
this.cbIsInGame.Location = new System.Drawing.Point(7, 64);
this.cbIsInGame.Name = "cbIsInGame";
this.cbIsInGame.Size = new System.Drawing.Size(77, 24);
this.cbIsInGame.Text = "В игре";
this.cbIsInGame.UseVisualStyleBackColor = true;
this.cbIsInGame.CheckedChanged += new System.EventHandler(this.cbIsInGame_CheckedChanged);
this.pPretender.Controls.Add(this.cbIsInGame);
this.pPretender.Controls.Add(this.cbEatCookie);
this.pPretender.Controls.Add(this.lSeatID);
this.pPretender.Controls.Add(this.lAnswer);
this.pPretender.Location = panelStartPoint;
this.pPretender.Name = "pPretender";
this.pPretender.Size = new System.Drawing.Size(277, 160);
this.pPretender.TabIndex = 2;
//Добавление панельки в основную форму
mainform.Controls.Add(pPretender);
}