线程跨类添加项列表框

时间:2012-09-17 21:13:09

标签: c# multithreading listbox

我遇到线程与类组合的问题。 对于我的问题,我已经制作了一个简单的代码来解释我的问题。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace RemoteMonitorServer
{
    public partial class RemoteMonitor : Form
    {
        Thread cThread;
        Server cServer;

        public RemoteMonitor()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            WriteLog("Programm started!");

            cServer = new Server();
            cThread = new Thread(new ThreadStart(cServer.StartServer));
            cThread.IsBackground = true;
            cThread.Start();
        }

        public void WriteLog(string sText)
        {
            MessageBox.Show(sText);
            listBox1.Items.Add(sText);
        }
    }
}

该类具有以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RemoteMonitorServer
{
    class Server
    {
        public void StartServer()
        {
            RemoteMonitor cTest = new RemoteMonitor();

            cTest.WriteLog("Thread started!");
        }
    }
}

现在,当我启动此代码时,列表框确实“程序已启动”!但不是“线程开始!”。 虽然我收到两条MessageBox消息,但我相信该方法正在被调用。 Visual Studio 2010中没有错误,有人可以告诉我这里我做错了吗?

3 个答案:

答案 0 :(得分:2)

public delegate void RunAtFormThreadCallBack(Control control, RunningAtFormThread method);
private void RunAtFormThread(Control control, RunningAtFormThread method)
{

        if (control.InvokeRequired)
        {
            var callback = new RunAtFormThreadCallBack(RunAtFormThread);
            control.Invoke(callback, new object[] { control, method });
        }
        else
            method.Invoke();
}

用法:

RunAtFormThread(listBox1, delegate
                            {
   // executing at control thread...
   listBox1.Items.Add(sText); 
   MessageBox.Show(sText);
});

答案 1 :(得分:0)

您可以使用SynchronizationContext将您的通话同步到用户界面。

// get a sync context
private readonly SynchronizationContext _sync = SynchronizationContext.Current;

然后,将方法发送到线程池以排队工作:

    public void WriteLog(string sText)
    {
        _sync.Send((state) => {
           MessageBox.Show(sText);
           listBox1.Items.Add(sText);
        }, null);
    }

请阅读我提供的链接,了解SendPost方法之间的差异以及上述示例中state对象的用途。

答案 2 :(得分:0)

好的,最后我明白了,它与RemoteMonitor的实例有关:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace RemoteMonitor
{
    public partial class RemoteMonitor : Form
    {
        Thread cThread;
        Server cServer;

        public RemoteMonitor()
        {
            InitializeComponent();   
        }

        private void RemoteMonitor_Load(object sender, EventArgs e)
        {
            WriteLog("Programm started!");

            cServer = new Server();
            cThread = new Thread(() => cServer.StartServer(this));
            cThread.Start();
        }

        public void WriteLog(string sText)
        {
            if (InvokeRequired)
            {
                Action action = () => lsbLogger.Items.Add(sText);
                lsbLogger.Invoke(action);
            }
            else
            {
                lsbLogger.Items.Add(sText);
            }
        }
    }
}

上课:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace RemoteMonitor
{
    class Server
    {
        public void StartServer(RemoteMonitor cRemoteMonitor)
        {
            cRemoteMonitor.WriteLog("Thread started!");
        }
    }
}

它就像一个魅力,感谢您的回答和评论!