首页 > 其他分享 >记录一次线程间通信PostThreadMessage(张三不是張三,张三是张三)

记录一次线程间通信PostThreadMessage(张三不是張三,张三是张三)

时间:2023-08-18 16:56:56浏览次数:40  
标签:IntPtr NativeMethods CharSet 间通信 线程 张三是 msg static public

事情是这样的,想使用线程间通信ChatGPT走一波

using System;
using System.Runtime.InteropServices;
using System.Threading;
public class Program
{
    // 定义常量,表示自定义消息
    private const int WM_CUSTOM_MESSAGE = 0x0400;
    // 定义用于接收消息的消息循环
    private static void MessageLoop()
    {
        while (true)
        {
            // 接收消息并处理
            if (NativeMethods.PeekMessage(out NativeMethods.MSG msg, IntPtr.Zero, 0, 0, 1))
            {
                // 处理消息
                if (msg.message == WM_CUSTOM_MESSAGE)
                {
                    Console.WriteLine("Received custom message!");
                }
                else if (msg.message == NativeMethods.WM_QUIT)
                {
                    break;
                }
                NativeMethods.TranslateMessage(ref msg);
                NativeMethods.DispatchMessage(ref msg);
            }
            Thread.Sleep(100); // 等待一段时间,防止CPU占用过高
        }
    }
    public static void Main()
    {
        // 创建一个新线程,并执行消息循环
        Thread thread = new Thread(MessageLoop);
        thread.Start();
        // 在主线程中发送消息
        int threadId = thread.ManagedThreadId;
        NativeMethods.PostThreadMessage(threadId, WM_CUSTOM_MESSAGE, IntPtr.Zero, IntPtr.Zero);
        // 等待一段时间,以便接收消息
        Thread.Sleep(1000);
        // 退出消息循环
        NativeMethods.PostThreadMessage(threadId, NativeMethods.WM_QUIT, IntPtr.Zero, IntPtr.Zero);
        // 等待线程结束
        thread.Join();
    }
}
public static class NativeMethods
{
    // 定义Windows常量
    public const int WM_QUIT = 0x0012;
    // 定义Windows消息结构
    [StructLayout(LayoutKind.Sequential)]
    public struct MSG
    {
        public IntPtr hwnd;
        public uint message;
        public IntPtr wParam;
        public IntPtr lParam;
        public uint time;
        public POINT pt;
    }
    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int x;
        public int y;
    }
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool PostThreadMessage(int threadId, uint msg, IntPtr wParam, IntPtr lParam);
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool PeekMessage(out MSG msg, IntPtr hwnd, uint filterMin, uint filterMax, uint remove);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool TranslateMessage(ref MSG msg);
    
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr DispatchMessage(ref MSG msg);
}

代码看上去非常棒。。。偶而。。。。运行结果不是想的那样。

细查PostThreadMessage 总是返回false.为啥?(ChatGPT一直各种PeekMessage,GetMessage顾左右而言它)

查了很多,突然有看别人使用window API

[DllImport("kernel32"), SuppressUnmanagedCodeSecurity]
static extern int GetCurrentThreadId();

为什么需要WindowsApi呢,想想这是通过window的。。。使用它的id合理。不对呀?

thread.ManagedThreadId; 

我给的是.net托管里的ID。

如此使用在  MessageLoop 线程中GetCurrentThreadId();再传给PoseThreadMessage... 结果差不多了。

讲白 就是张三不是張三,张三是张三。


 

标签:IntPtr,NativeMethods,CharSet,间通信,线程,张三是,msg,static,public
From: https://www.cnblogs.com/stweily/p/17640988.html

相关文章

  • 线程管理
    一、基本概念1、线程是进程的执行路线,它是进程内部的控制序列,线程是进程的一部分,进程是一个资源单位,而线程是执行单位,线程是进程执行的实体,负责真正的执行2、线程是轻量级的,没有自己的代码段、数据段、bss段、堆、环境变量、命令行参数、文件描述符、信号处理函数、当前工作目录......
  • SimpleDateFormat 线程安全问题修复方案
    问题介绍在日常的开发过程中,我们不可避免地会使用到JDK8之前的Date类,在格式化日期或解析日期时就需要用到SimpleDateFormat类,但由于该类并不是线程安全的,所以我们常发现对该类的不恰当使用会导致日期解析异常,从而影响线上服务可用率。以下是对SimpleDateFormat类不恰当......
  • java线程死锁怎么处理
    在Java中,线程死锁是指两个或多个线程被阻塞,因为它们互相等待对方释放资源。这种情况下,线程将永远无法继续执行下去。处理线程死锁的方法之一是使用以下步骤:1.分析死锁:确定哪些线程和资源参与了死锁,并找出造成死锁的原因。你可以使用工具如线程转储分析工具(ThreadDumpAnalyzer)或......
  • 【Java技术专题】「入门到精通系列教程」深入探索Java特性中并发编程体系的原理和实战
    并发编程介绍当今软件开发领域越来越强调性能和伸缩性,因此,利用并发编程可以更好地利用计算资源,提高应用程序的性能和响应速度。以下是一些关于并发编程的相关信息供您参考。什么是并发编程并发编程是指在一个程序中同时执行多个独立的计算任务,并通过各种手段来协调不同任务之间的交......
  • C++ 多线程详解之异步编程 std::packaged_task
    std::packaged_task将任何可调用对象(比如函数、lambda表达式等等)封装成一个task,可以异步执行。执行结果可以使用std::future获取。比如下面的例子,构造一个std::packaged_task后,get_future()函数返回一个std::future对象,可以获取task异步或者同步执行的结果。#includ......
  • 线程与进程的区别
    线程与进程的区别?线程是指进程内的一个执行单元,也是进程内的可调度实体.与进程的区别:地址空间:进程内的一个执行单元;进程至少有一个线程;它们共享进程的地址空间;而进程有自己独立的地址空间;资源拥有:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源线程......
  • 远程调试&线程检查&性能检查
    vs2022的一些调试技巧——远程调试&线程检查&性能检查visualstudio一直都是.net/c#开发人员最受欢迎的编译器,除了强大的代码提示和项目模板,还拥有大量的调试工具,这一期我们介绍下codefreeze阶段的一些调试技巧。包括测试环境/生产环境下的远程调试,线程调试,以及性能监控调试。......
  • 在C++中实现多线程异步TCP消息发送
    本文主要解释了在C++中如何实现一个多线程,异步发送TCP消息的系统。我们将会用到C++的标准库和Boost.Asio库。基础知识TCP(TransmissionControlProtocol):是一种面向连接的、可靠的、基于字节流的通信协议。它在两个网络节点之间创建一个稳定的连接,以便可以交换字节流。多线程编程:......
  • 进程 线程
    个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于进程,使得多线程程序的并发性高。另外,进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过程中与进程还是有区别的。 每个独立的线程有一个程序运行的入口、......
  • 爬虫速度翻倍!多线程技术助你提升批量爬虫采集效率
       今天要和大家分享一些关于如何利用多线程技术提升批量爬虫采集效率的实用技巧。如果你也在面对大量数据采集任务的时候疲于奔命,那么这些经验对你来说将非常有帮助。废话不多说,让我们开始吧!1.多线程是什么?——理解多线程的概念多线程是指在一个程序中同时运行多个......