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!");
        }
    }
}

さて、このコードを開始すると、リストボックスに「Programm started!」と表示されます。「スレッドが開始されました!」ではありません。2 つの 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

わかりました、ようやくわかりました。これは、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 に答える
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);
    }

SendPostメソッドの違い、およびstate上記の例のオブジェクトの使用法については、私が提供したリンクを参照してください。

于 2012-09-17T21:25:29.587 に答える