0

我有一个任务,我需要从另一个线程向一个线程发送消息。我有这个任务的课程,这里是:

public class MyThread
{
    public Thread Thrd { get; set; }
    public MyThread Next { get; set; }


    public MyThread()
    {
        Thrd = new Thread(Work);
    }

    public void Start()
    {
        Thrd.Start();
    }

    private void Work()
    {
        while (true)
        {
            if (//Has message to receive)
            {
                //Get message and do work
                //Send message to the Next.Thrd
            }
        }
    }
    
}

作为一条消息,我只需要发送一个整数。我发现像 PostThreadMessageA 和 GetMessageA 这样对我有用的函数,对吗?另外,这些需要线程句柄,我怎样才能得到它?最后,是否有一个函数可以检查该线程是否有消息要接收(我可以放置而不是“//有消息要接收”)?

4

2 回答 2

0

这些需要线程句柄,我怎样才能得到它?

您可以GetCurrentThreadId在线程启动后使用来获取线程ID。

是否有一个函数可以检查该线程是否有消息要接收?

是的,GetMessage/ PeekMessageGetMessage将等待消息到达,但PeekMessage不会等待消息发布后再返回。)

下面是win32的解决方案。在主线程中创建了两个线程thread1、thread2(thread1.Next = thread2)。主线程向thread1发送数据,然后thread1接收到消息并将其数据发送给thread2:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp
{
    public class MyThread
    {
        
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int x;
            public int y;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct MSG
        {
            public IntPtr hwnd;
            public int message;
            public UIntPtr wParam;
            public IntPtr lParam;
            public int time;
            public POINT pt;
            public int lPrivate;
        }
        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetCurrentThreadId();
        
        [DllImport("User32.dll",SetLastError = true,CharSet =CharSet.Auto)]
        public static extern bool PostThreadMessage(int idThread, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool GetMessage(out MSG Msg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
        [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool PeekMessage(out MSG Msg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax,uint wRemoveMsg);
        public static uint WM_USER = 0x0400;
        public Thread Thrd { get; set; }
        public MyThread Next { get; set; }
        public int ThreadId { get; set; }
        public int data { get; set; }
        public MyThread()
        {
            Thrd = new Thread(Work);
            ThreadId = -1;
        }

        public void Start()
        {
            Thrd.Start();
        }
        public static bool SendTo(int data, MyThread target_thread)
        {
            IntPtr lparam = new IntPtr(data);
            return PostThreadMessage(target_thread.ThreadId, WM_USER, IntPtr.Zero, lparam);
        }
        private void Work()
        {
            ThreadId = GetCurrentThreadId();
            data = ThreadId;
            while (true)
            {
                MSG msg = new MSG();
                IntPtr hwnd = new IntPtr(-1);
                if (GetMessage(out msg, IntPtr.Zero, 0, 0))
                {
                    Console.WriteLine("received : " + msg.lParam.ToInt32());
                    if (Next != null)
                        SendTo(data, Next);
                }
            }
        }

    }
    class Program
    {
        static void Main(string[] args)
        {
            MyThread thread1 = new MyThread();
            MyThread thread2 = new MyThread();
            thread1.Next = thread2;
            thread1.Start();
            thread2.Start();

            //To Do
            //To Ensure that the thread has been started, and the thread ID has been obtained through GetCurrentThreadId
            Thread.Sleep(1000); 

            MyThread.SendTo(50, thread1);

            //To Do
        }
    }
}
于 2020-12-25T06:35:21.293 回答
-1

为了得到我想要的,我使用了这些函数:

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool PeekMessage(
        out InternalMessage lpInternalMessage,
        IntPtr hWnd,
        uint wMsgFilterMin,
        uint wMsgFilterMax,
        uint wRemoveMsg
    );

    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool PostThreadMessage(
        uint threadId,
        uint msg,
        UIntPtr wParam,
        IntPtr lParam
        );

    [DllImport("kernel32.dll")]
    public static extern uint GetCurrentThreadId();

而且我还需要定义这样的结构:

[StructLayout(LayoutKind.Sequential)]
public struct InternalMessage
{
    public IntPtr hwnd;
    public uint message;
    public UIntPtr wParam;
    public IntPtr lParam;
    public int time;
    public Point pt;
    public int lPrivate;
}
于 2020-12-25T12:05:00.457 回答