C # Вызов управления из другого потока - PullRequest
2 голосов
/ 29 ноября 2010

Я работаю над серверной программой, которая использует многопоточность. Проблема в том, что есть несколько классов и множество потоков, которым нужен доступ к определенному TextBox. (TbLog)

Метод (Log) выглядит так:

using System;
using System.Windows.Forms;
using System.ComponentModel;

namespace Server
{
    public delegate void Logs(string message);

    public partial class Menu : Form
    {    
        public Menu()
        {
            InitializeComponent();
        }

        public void Log(string message)
        {
            if (this.tbLog.InvokeRequired)
                this.tbLog.BeginInvoke(new MethodInvoker(delegate() { tbLog.Invoke(new Logs(Log)); }
            )); 
            else
                this.tbLog.Text += DateTime.Now + ": " + message + Environment.NewLine;
        }
    }
}

Конечно, я пробовал другие вещи, и это не одна из моих лучших попыток. Проблема в том, что даже если я вызываю метод из другого потока / класса следующим образом:

namespace Server.Connections
{
    class packetSend
    {
        static bool sendPacket(string rawPacket)
        {
            Menu menu = new Menu();

            menu.Log("I'm a message");

            return true;
        }
    }
}

- будет работать только из основного потока. И я думаю, это как-то связано с пространством имен или потому, что я использую:

Menu menu = new Menu();

Ответ, вероятно, очевиден, но я его не вижу. Вздох

Помощь будет очень признательна.

Ответы [ 2 ]

3 голосов
/ 29 ноября 2010

Почему вы создаете новую форму каждый раз, когда вы регистрируете сообщение?

Как обычно работает invoke:

  1. С, например, При запуске приложения вы создаете форму, в которой отображается журнал. Это в главном потоке;

  2. Затем, когда вам нужно войти, вы получаете ссылку на эту форму;

  3. Затем, с помощью Invoke, вы отправляете журнал в эту форму.

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

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

0 голосов
/ 29 ноября 2010

Ответ проще, чем вы думаете ( вы пропускаете возврат , поэтому он всегда запускается из неправильного потока). Вы можете немного упростить свой код:

namespace Server
{
    public delegate void Logs(string message);

    public partial class Menu : Form
    {
        public Menu()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            throw new NotImplementedException();
        }

        public void Log(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(Log), message);
                return;
            }
            else
            {
                this.tbLog.Text += DateTime.Now + ": " + message + Environment.NewLine;
            }
        }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...