小编J..*_*...的帖子

.net中的元组(T1)/ Singleton的目的是什么?

.net 4中的元组类型之一是单元素元组.我只是想知道这个结构的目的是什么?

我看到的唯一用途是在8+元组中使用,因为它可以分配给TRest,它实际上是有意义的.是吗?或者还有其他目的吗?

.net tuples

32
推荐指数
2
解决办法
1076
查看次数

非窗口类中的自定义消息 - 需要默认处理程序吗?

我有一个类(TObject):

private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage); message TH_MYMESSAGE;
Run Code Online (Sandbox Code Playgroud)

哪里 TH_MYMESSAGE = WM_USER + 1

在类构造函数中:

FHwnd := AllocateHWND(HandleMyMessage);
Run Code Online (Sandbox Code Playgroud)

接收引用的唯一对象FHwnd是私有自定义TThread(在此类中创建)以及它发布的唯一消息TH_MYMESSAGE.我的理解是,message程序声明中的指令仅限制其处理TH_MYMESSAGE.

这在测试中运行良好,但是在集成到更大的应用程序中时,我得到的反馈HandleMyMessage也会触发其他消息(显然有不希望的结果).

这可以通过添加if Message.Msg <> TH_MYMESSAGE then Exit;来轻松纠正HandleMyMessage.我的问题是:为什么会这样?

我最好的猜测是,AllocateHWND已经取得HandleMyMessage的等效DefWndProc尽管拥有它message的指令.有没有正确的方法来实现我缺少的?

delphi multithreading message hwnd delphi-xe2

19
推荐指数
1
解决办法
1239
查看次数

TParallel的奇怪行为.对于默认的ThreadPool

我正在尝试Delphi XE7 Update 1的并行编程功能.

我创建了一个简单的TParallel.For循环,基本上做了一些虚假的操作来消磨时间.

我在AWS实例(c4.8xlarge)上的36 vCPU上启动了该程序,试图了解并行编程的优势.

当我第一次启动程序并执行TParallel.For循环时,我看到了显着的增益(虽然admitelly比我预期的36个vCPU少很多):

Parallel matches: 23077072 in 242ms
Single Threaded matches: 23077072 in 2314ms
Run Code Online (Sandbox Code Playgroud)

如果我不关闭程序并在不久之后再次在36 vCPU机器上运行传递(例如,立即或大约10-20秒后),并行传递会恶化很多:

Parallel matches: 23077169 in 2322ms
Single Threaded matches: 23077169 in 2316ms
Run Code Online (Sandbox Code Playgroud)

如果我没有关闭程序并等待几分钟(不是几秒钟,但几分钟)再次运行传递之前,我再次得到第一次启动程序时得到的结果(响应时间提高了10倍) .

在36个vCPU机器上启动程序后的第一次传递总是更快,因此看起来这种效果仅TParallel.For在程序中第二次调用a时发生.

这是我正在运行的示例代码:

unit ParallelTests;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  System.Threading, System.SyncObjs, System.Diagnostics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    SingleThreadCheckBox: TCheckBox;
    ParallelCheckBox: TCheckBox;
    UnitsEdit: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { …
Run Code Online (Sandbox Code Playgroud)

delphi parallel-processing rtl-ppl

18
推荐指数
1
解决办法
2110
查看次数

我的32位应用程序可以做些什么来消耗千兆字节的物理RAM?

几个月前,一位同事提到我,我们的一个内部Delphi应用程序似乎占用了8 GB的RAM.我告诉他了:

那是不可能的

32位应用程序仅具有32位虚拟地址空间.即使存在内存泄漏,它可以消耗的内存最多也是2 GB.之后,分配将失败(因为虚拟地址空间中不会有空白空间).在内存泄漏的情况下,虚拟页面将被换出到页面文件,从而释放物理RAM.

但他指出Windows资源监视器表明系统上可用的RAM不到1 GB.虽然我们的应用程序仅使用220 MB的虚拟内存:关闭它可以释放8 GB的物理RAM.

所以我测试了它

我让应用程序运行了几个星期,今天我终于决定测试它.

首先,我在关闭应用程序之前查看内存使用情况:

  • 工作集(RAM)为241 MB
  • 使用的总虚拟内存:409 MB

在此输入图像描述

我使用资源监视器来检查应用程序使用的内存,以及正在使用的总RAM:

  • 应用程序分配的虚拟内存:252 MB
  • 使用中的物理内存:14 GB

在此输入图像描述

然后关闭应用程序后的内存使用情况:

  • 使用的物理内存:6.6 GB (低7.4 GB)

在此输入图像描述

我还使用Process Explorer来查看前后物理RAM使用情况的细分.唯一的区别是8 GB的RAM 确实是未提交的,现在是免费的:

| Item                          | Before     | After     |
|-------------------------------|------------|-----------|
| Commit Charge (K)             | 15,516,388 | 7,264,420 |
| Physical Memory Available (K) |  1,959,480 | 9,990,012 |
| Zeroed Paging List  (K)       |    539,212 | 8,556,340 |
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

注意:Windows有时会浪费时间将所有内存清零,而不是简单地将其放在备用列表中,并根据需要将其清零(因为需要满足内存请求).

这些都没有解释RAM正在做什么(你坐在那里什么!你包含什么!?)

那段记忆里有什么! …

windows delphi winapi delphi-5 virtual-memory

17
推荐指数
1
解决办法
948
查看次数

可以从多个线程安全地访问静态数组吗?

如果保证每个线程只读/写一个特定的数组子集,多个线程可以在同一个(静态)数组上工作,而不需要求助于关键部分等?

编辑 - 这是针对非参考计数类型的数组及其记录/打包记录的特定情况.

如果是,有任何警告吗?

我的直觉是肯定的,但我的直觉有时可能是一个不可靠的信息来源.

delphi multithreading delphi-xe2

12
推荐指数
2
解决办法
2807
查看次数

泛型无法正确解析方法类型

考虑以下 :

{$APPTYPE CONSOLE}

uses
  Generics.Collections;

type
  TObjProc = procedure of object;
  TFoo = class
    public procedure DoFoo;
    public procedure DoBar;
  end;

procedure TFoo.DoFoo;
begin
  WriteLn('foo');
end;

procedure TFoo.DoBar;
begin
  WriteLn('bar');
end;

var
  ProcList : TList<TObjProc>;
  Foo : TFoo;
  aProc : TObjProc;
begin
  Foo := TFoo.Create;
  ProcList := TList<TObjProc>.Create;
  ProcList.Add(Foo.DoFoo);
  ProcList.Add(Foo.DoBar);
  for aProc in ProcList do aProc;
  ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)

这产生了预期的输出

foo
bar
Run Code Online (Sandbox Code Playgroud)

现在假设我们要从列表中分配一个过程.列举作品,如上所述.这也有效:

aProc := ProcList.Items[0];
aProc;
Run Code Online (Sandbox Code Playgroud)

但这会引发编译器错误:

aProc := ProcList.First;
// E2010 Incompatible types: 
//'procedure, untyped pointer or …
Run Code Online (Sandbox Code Playgroud)

delphi generics delphi-xe2

12
推荐指数
1
解决办法
255
查看次数

有没有办法只跟踪Delphi中的项目源?

我正在使用Delphi 2010,我想知道是否有一种方法可以跟踪项目中的代码,而无需跟踪调用包含的VCL.

例如 - 您输入一个断点然后使用Shift+ F7来逐行跟踪.现在你在VCL中调用了一些冗长的过程 - 在我的例子中,它通常是一个Measurement Studio或其他组件,用于绘制一堆I/O,OPC或其他位的doodads.无论如何,发生的事情是调试器跳出活动源文件,打开组件源,并逐行跟踪.通常这是我不关心的数百或数千行代码 - 我只想让它执行并返回到MY项目中的下一个源代码行.

显然你可以通过在外部调用的每个实例周围设置断点来实现这一点,但通常有太多不能使其变得切实可行 - 每次我想要逐步执行一段代码时,我会花一小时设置一百个断点.

是否有设置或工具可以做到这一点?允许用户跟踪项目中的代码,同时静默执行项目外部的代码?

delphi debugging trace project delphi-2010

11
推荐指数
1
解决办法
2233
查看次数

如何从具有管理员权限的应用程序接收键盘输入到非管理员应用程序?

我编写了一个具有覆盖类型窗口的应用程序,可以通过热键显示和隐藏,而另一个应用程序具有焦点.所述其他应用程序是使用管理员权限运行的DirectX游戏.

我已经尝试了3种可能的解决方案,当我在其他应用程序中按下热键时收到通知,其中2种工作,但要求我的应用程序也具有管理权限.这是可以接受的,但我宁愿有一个不需要这些特权的解决方案.我确信必须有一种方法,因为像TeamSpeak这样的应用程序确实能够在不以管理员身份运行的情况下接收输入.

我已经尝试过了:

  1. RegisterHotkey - 不适合,因为它在DirectX窗口中不起作用.
  2. SetWindowsHookEx - 作为通用键盘钩子,但仅具有管理员权限.
  3. GetAsyncKeyState - 用于检查指定的热键,但不能再次使用管理员权限.

所以,是的,如果有人可以为不同的解决方案提供一个想法,我会非常感激,因为我无法想到......我正在使用Delphi,但是因为我依赖Windows API,所以我不这样做认为解决方案将特定于语言.

delphi winapi keyboard-hook uipi

11
推荐指数
1
解决办法
746
查看次数

为什么不提高EInvalidPointer?

Delphi 文档说明:

永远不要直接引发EInvalidPointer异常.EInvalidPointer由内存管理器在内部引发.

我正在编写一个自定义基类作为替代TInterfacedObject,尽可能地遵循RTL实现,并且通过示例看,TInterfacedObject在RTL实现BeforeDestruction为:

procedure TInterfacedObject.BeforeDestruction;
begin
  if RefCount <> 0 then
    Error(reInvalidPtr);  
end;
Run Code Online (Sandbox Code Playgroud)

其中Error(reInvalidPtr)提出了EInvalidPointer通过各种本地的RTL单元范围的方法.

如果我正在编写自己的课程,我应该如何实施BeforeDestruction?为什么不这样做?:

procedure TMyInterfacedObject.BeforeDestruction;
begin
  if RefCount <> 0 then
    raise EInvalidPointer.CreateRes(@SInvalidPointer) at ReturnAddress;
end;
Run Code Online (Sandbox Code Playgroud)

InvalidPointer声明的全局异常对象是否有特殊之处SysUtils?如果这一个坏主意,那么在这里简单地提出一个自定义异常是否明智?

delphi invalid-pointer

11
推荐指数
2
解决办法
238
查看次数

在ESP下面写下是否有效?

对于32位Windows应用程序,使用ESP下面的堆栈内存进行临时交换空间而不显式减少ESP是有效的吗?

考虑一个返回浮点值的函数ST(0).如果我们的价值目前在EAX,我们会,例如,

PUSH   EAX
FLD    [ESP]
ADD    ESP,4  // or POP EAX, etc
// return...
Run Code Online (Sandbox Code Playgroud)

或者不修改ESP寄存器,我们可以:

MOV    [ESP-4], EAX
FLD    [ESP-4]
// return...
Run Code Online (Sandbox Code Playgroud)

在这两种情况下都会发生同样的事情,除了在第一种情况下我们注意在使用内存之前递减堆栈指针,然后在之后递增它.在后一种情况下,我们没有.

尽管有任何实际需要在堆栈上持久保存这个值(重入问题,在PUSH返回值和读取值之间的函数调用等),有没有任何根本原因,为什么写入ESP下面的堆栈这样会无效?

windows x86 assembly abi

11
推荐指数
3
解决办法
447
查看次数