2

我有线程与类结合的问题。对于我的问题,我制作了一个简单的代码来解释我的问题。

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 中没有错误,有人可以告诉我我在这里做错了什么吗?

4

3 回答 3

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);
});
于 2012-09-17T22:47:35.490 回答
0

您可以使用SynchronizationContext将您的调用同步到 UI。

// 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);
    }

在我提供的链接上阅读更多内容,以了解Send和方法之间的区别以及上面示例中对象Post的用途。state

于 2012-09-17T21:25:29.587 回答
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!");
        }
    }
}

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

于 2012-09-18T14:56:01.013 回答