如何使用c#中的winapi32函数在线程之间发送消息?
我有一个任务,需要从另一个线程向一个线程发送消息。 我有一个类来完成这项任务,它是:如何使用c#中的winapi32函数在线程之间发送消息?,c#,multithreading,winapi,C#,Multithreading,Winapi,我有一个任务,需要从另一个线程向一个线程发送消息。 我有一个类来完成这项任务,它是: public class MyThread { public Thread Thrd { get; set; } public MyThread Next { get; set; } public MyThread() { Thrd = new Thread(Work); } public void Start() {
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这样的函数对我很有用,是吗?而且,这些需要一个线程句柄,我怎样才能得到它?最后,是否有一个函数可以检查此线程是否有要接收的消息(我可以将其替换为“/”要接收的消息)
这些需要一个线程句柄,我怎样才能得到它
您可以使用在线程启动后获取线程ID
是否有功能检查是否有消息要接收
这条线用的是什么
是,/(GetMessage
将等待消息到达,但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
}
}
}
为了得到我想要的,我使用了以下函数:
[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;
}
PostMessage()需要一个窗口(不是线程)、一个消息循环和一个线程安全队列(由操作系统提供)。您没有或不需要的基础架构。这只是生产者-消费者问题的一个解决方案,是.NET中的标准解决方案。是的,我看到了一个使用ConcurrentQueue的解决方案,但我需要使用这些api函数。我可能是指PostThreadMessageA而不是PostMessage为什么需要使用这些函数?很可能你的想法是错误的。@DavidHeffernan我知道这些函数很容易出错,但使用它们是我任务的一部分。你是想解决问题,还是只想调用这些函数?