RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 784054
Accepted
dr. F.I.N.
dr. F.I.N.
Asked:2020-02-12 22:27:21 +0000 UTC2020-02-12 22:27:21 +0000 UTC 2020-02-12 22:27:21 +0000 UTC

如何在单独的线程中“取出”对象的方法?

  • 772

我正在编写一个模拟设备操作的程序(一次几个)。数据交换有条件地通过 RS-485 网络“发生”,即 该程序连接到网络并将“虚拟仪器”添加到网络中。它的实现如下: 1. 有一个对象“数据总线”。本质上是相同类型对象的容器。从一个 Send 对象接收会分发给所有其他对象。2. 总线对象。它们可能具有不同的功能,但它们实现了一个带有 Receive 功能(从总线接收数据)的基本接口。总线对象有两种类型:“虚拟设备”-(根据接收到的数据,进行计算并将结果“发送”到“总线”),“数据源”(例如,对象打开一个 COM端口,或 TCP,或其他,并将接收到的数据传输到“总线”,然后从总线返回到端口)。

所以。一切都很好。但我想把所有这些放在一个单独的线程中。这是干什么用的——所有对象“发起”事件(TNotifyEvent),例如 OnDataReceive、OnChanged 等。这些事件的处理(程序窗口中相关信息的视觉反映)可能需要“长时间”(对仿真至关重要)。因此,主设备(RS-485 总线上的真实设备)“丢失”了虚拟设备。

我无法想象完整的实现(因此实现它,不知道具体要做什么)。它看起来像这样: - 我们创建一个“总线”对象 - 我们创建 - 将必要的对象添加到“总线” - 我们启动流程(“RunEmulation”总线的某些方法),启动“数据源”对象. - 来自“源”的所有数据都被发送到仿真流,它被发送到接收者,被处理。- 在事件“发起”的情况下,将带有必要信息的 PostMessage 发送到总线,并且总线已经在主线程中调用了 OnDataReceive、OnChanged 等。(然后消息将被排队,用户处理不会影响仿真线程)

像这样的东西。也许有人解决了类似的问题,或者只是对正确的实施方法有想法

алгоритм
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    dr. F.I.N.
    2020-02-19T17:28:13Z2020-02-19T17:28:13Z

    感谢大家。结果如下:1)处理消息的线程:

    TEmulatorThread = class(TThread)
    private
      FOwnerHandle: THandle;
    protected
      procedure Execute; override;
      property OwnerHandle: THandle read FOwnerHandle;
    public
      constructor Create(OwnerHandle: THandle);
    end;
    
    constructor TEmulatorThread.Create(OwnerHandle: THandle);
    begin
      FOwnerHandle := OwnerHandle;
      inherited Create(False);
    end;
    
    procedure TEmulatorThread.Execute;
    var
      msg: TMsg;
    begin
      with TDataBus.Create(OwnerHandle) do
      try
        while not Terminated do
        begin
          try
            while PeekMessage(msg, 0, 0, 0, PM_REMOVE) do
              if msg.message = WM_TERMINATE then
                Terminate
              else
                DispatchMessage(msg);
            if not Terminated then
              WaitMessage;
          except
            PostMessage(OwnerHandle, WM_EXCEPTION, Integer(AcquireExceptionObject), 0);
          end;
        end;
      finally
        Free;
      end;
    end;
    

    2)模拟器本身(来自数据总线的消息接收器):

    constructor TEmulator.Create;
    begin
      inherited;
      FDataBus := nil;
      FWindowHandle := AllocateHWnd(WindowProc);
      FThread := TEmulatorThread.Create(FWindowHandle);
    end;
    
    destructor TEmulator.Destroy;
    begin
      PostThreadMessage(FThread.ThreadID, WM_TERMINATE, 0, 0);
      FThread.WaitFor;
      FThread.Free;
      DeallocateHWnd(FWindowHandle);
      inherited;
    end;
    
    procedure TEmulator.WindowProc(var Message: TMessage);
    begin
      with Message do
        case msg of
          WM_DATABUS_NOTIFY:
            case WParam of
              DB_CREATED:
                FDataBus := TDataBus(LParam);
              DB_DESTROYING:
                FDataBus := nil;
              DB_OBJECT_ADDED:
                ;
              DB_OBJECT_DELETED:
                ;
            end;
          WM_OBJECT_NOTIFY:
            ;
          WM_EXCEPTION:
            begin
              raise Exception(WParam);
            end;
        else
          DefWindowProc(FWindowHandle, msg, WParam, LParam);
        end;
    end;
    

    3)数据总线(仿真器通知):

    procedure TBONDataBus.AfterConstruction;
    begin
      PostMessage(FOwnerHandle, WM_DATABUS_NOTIFY, DB_CREATED, Integer(Self));
    end;
    
    procedure TBONDataBus.BeforeDestruction;
    begin
      PostMessage(FOwnerHandle, WM_DATABUS_NOTIFY, DB_DESTROYING, 0);
      inherited;
    end;
    

    流中对象的所有 getter/setter 都被临界区“覆盖”。

    • 0

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5