小编dum*_*uch的帖子

锁定多个读者单一作家

我有一个内存数据结构,由多个线程读取,只由一个线程写入.目前我正在使用一个关键部分来使这个访问线程安全.不幸的是,即使只有另一个读者访问它,它也会阻止读者.

有两种方法可以解决这个问题:

  1. 使用TMultiReadExclusiveWriteSynchronizer
  2. 通过使用无锁方法消除任何阻塞

对于2.到目前为止,我已经得到了以下内容(任何无关紧要的代码都被遗漏了):

type
  TDataManager = class
  private
    FAccessCount: integer;
    FData: TDataClass;
  public
    procedure Read(out _Some: integer; out _Data: double);
    procedure Write(_Some: integer; _Data: double);
  end;

procedure TDataManager.Read(out _Some: integer; out _Data: double);
var
  Data: TDAtaClass;
begin
  InterlockedIncrement(FAccessCount);
  try
    // make sure we get both values from the same TDataClass instance
    Data := FData;
    // read the actual data
    _Some := Data.Some;
    _Data := Data.Data;
  finally
    InterlockedDecrement(FAccessCount);
  end;
end;

procedure TDataManager.Write(_Some: integer; _Data: double);
var
  NewData: TDataClass;
  OldData: …
Run Code Online (Sandbox Code Playgroud)

delphi multithreading lock-free

5
推荐指数
1
解决办法
5596
查看次数

Delphi/Borland Pascal STR 程序如何轮转

Borland Pascal 7 和 Delphi 2007 都得到了过程 STR,它接受一个数字、一个长度和一个精度,并将其转换为这样的字符串:

str(9.234:5:1, s); // -> s = '  9.2'
Run Code Online (Sandbox Code Playgroud)

如果舍入是非歧义的,一切都很好,但如果不是(0.5 -> 向上或向下?),则存在问题:它似乎取决于 BP 中的浮点数据类型,但在 Delphi 2007 中显然是一致的:

BP:

var
  e: extended;
  d: double;
begin
  d := 2.15;
  e := 2.15;
  str(d:5:1, s); { -> s = '  2.1' }
  str(e:5:1, s); { -> s = '  2.2' }
  { but: }
  d := 2.25
  e := 2.25
  str(d:5:1, s); { -> s = '  2.3' }
  str(e:5:1, s); { -> s = ' …
Run Code Online (Sandbox Code Playgroud)

delphi pascal rounding delphi-2007

5
推荐指数
1
解决办法
1927
查看次数

如何将svn url重定向到另一个域?

背景:DynDNS现在已开始要求每月登录一次以保持其免费帐户处于活动状态(以前您只需每月更新一次IP地址).我相信我迟早会忘记这样做并失去我的帐户.

我使用mysvn.dyndns.org来访问服务器上的subversion存储库,该服务器也可以通过svn.mydomain.com访问(截至目前).不幸的是,大多数项目也指的是也位于mysvn.dyndns.org的外部,我真的不想通过所有项目(> 100)并改变外部,因为这可能需要几个小时而且容易出错.

有没有办法配置Windows或subversion/TortoiseSVN客户端将一个域重定向到另一个域?

例如:

https://mysvn.dyndns.org/svn/blablub

应重定向到

https://svn.mydomain.com/svn/blablub

我知道我可以向主机添加一个条目以重定向到一个IP地址,但我更希望重定向到一个域名.

svn dns tortoisesvn redirect svn-externals

5
推荐指数
2
解决办法
3388
查看次数

我可以从InstallAware setup.exe安装Delphi IDE而无需复制文件到c:\ programdata吗?

Delphi IDE在最近几个版本(2010,XE,XE2,XE3,XE4)中使用InstallAware作为安装程序.如果安装了所有IDE版本,则使用正常的setup.exe安装会将几GB文件复制到c:\ programdata中.

安装程序会快速占用磁盘空间,特别是对于使用昂贵的SSD硬盘的用户而言.

是否可以在不将文件复制到c:\ ProgramData的情况下设置Delphi IDE?是否建议在安装后手动删除这些文件?卸载以前版本的IDE会删除这些文件,但作为组件制造商,我需要这些IDE进行测试.

delphi

5
推荐指数
1
解决办法
901
查看次数

当用户单击任务栏按钮时,为什么模态Delphi表单不接收WM_SYSCOMMAND?

在Windows 8.1上运行的Delphi(2007)程序中,我希望在用户单击属于我的程序的任务栏按钮时收到通知.所以我正在捕获WM_SYSCOMMAND,在这种情况下通常会发送.

这适用于程序的主窗口.

如果模态窗口处于活动状态(使用Form2.ShowModal打开),则相同的代码无法捕获WM_SYSCOMMAND,无论是在main for还是在modeal形式中.有什么不同吗?有没有办法改变这个?

这是我添加到两种形式的代码:

unit unit1;

interface

type
  TForm1 = class(TForm)
    // [...]
    procedure WMSysCommand(var Msg: TWMSysCommand); message WM_SYSCOMMAND;
  end;

 // [...]

implementation

 // [...]

procedure Tf_dzProgressTest.WMSysCommand(var Msg: TWMSysCommand);
begin
  inherited; // place breakpoint here
end;

 // [...]

end.
Run Code Online (Sandbox Code Playgroud)

我还尝试使用Application.OnMessage或TApplicationEvents组件,甚至覆盖表单的WndProc方法.当模态窗体处于活动状态时,它们都不能捕获WM_SYSCOMMAND.

windows delphi delphi-2007

5
推荐指数
1
解决办法
1120
查看次数

如何在Delphi中使用IVBSAXXMLReader停止解析XML文档?

为了在Delphi(2007)程序中快速解析一些大型XML文档,我实现了IVBSAXContentHandler接口并使用它如下:

FXMLReader := CoSAXXMLReader60.Create;
FXMLReader.contentHandler := Self;
FXMLReader.parseURL(FXmlFile);
Run Code Online (Sandbox Code Playgroud)

这很好,只要我简单地解析整个文件,但是一旦找到了我要查找的内容,我就想停止.所以我的IVBSAXContentHandler.startElement实现会检查某些条件,当它为true时应该中止进一步的解析.我试过这个:

procedure TContentHandler.startElement(var strNamespaceURI, strLocalName,  strQName: WideString; const oAttributes: IVBSAXAttributes);
begin
  if SomeCondition then
    SysUtils.Abort;
end;
Run Code Online (Sandbox Code Playgroud)

不幸的是,这引起了相当无益的EOleException"灾难性失败".(我也尝试使用相同的结果引发自定义异常.)

MSDN说如下:

ErrorHandler接口实质上允许XMLReader通知它想要中止处理的ContentHandler实现.相反,ContentHandler实现可以向XMLReader指示它想要中止处理.这可以通过简单地引发特定于应用程序的异常来实现.一旦实现找到它正在寻找的内容,这对于中止处理特别有用:

Private Sub IVBSAXContentHandler_characters(ByVal strChars As String)
' I found what I was looking for, abort processing
  Err.Raise vbObjectError + errDone, "startElement", _
        "I got what I want, let's go play!"
End Sub
Run Code Online (Sandbox Code Playgroud)

所以,显然我还需要以某种方式实现IVBSAXErrorHandler接口.该接口需要三种方法:

procedure TContentHandler.error(const oLocator: IVBSAXLocator;
  var strErrorMessage: WideString; nErrorCode: Integer);
begin

end;

procedure TContentHandler.fatalError(const oLocator: IVBSAXLocator;
  var strErrorMessage: WideString; nErrorCode: …
Run Code Online (Sandbox Code Playgroud)

delphi msxml sax delphi-2007

5
推荐指数
1
解决办法
560
查看次数

如果加载DLL无法找到依赖项,有没有办法捕获错误?

我正在编写一个Windows 32位程序,可以使用多个可能的dll之一.因此它尝试依次加载每个dll SysUtils.SafeLoadLibrary,如果加载成功,则使用该dll.

不幸的是,其中一些dll与其他dll静态相关.这些dll可能在计算机中丢失.在那种情况下,我得到对话告诉我

[myprogram]:[myprogram.exe]系统错误

程序无法启动,因为您的计算机缺少[某些DLL名称].尝试重新安装该程序以解决此问题."

按下该对话框上的OK按钮后,程序将获取错误代码并尝试其他一个dll然后工作正常.

而不是向用户显示该对话框,我希望我的程序默默地忽略它.

我怎么能做到这一点?

如果重要:我的程序是用Delphi 2007编写的.Windows版本是Windows 8.1,但该程序也适用于其他Windows版本> = Windows XP.

我尝试过,SetErrorMode(SEM_FAILCRITICALERRORS)但没有任何区别.

delphi winapi delphi-2007

5
推荐指数
1
解决办法
493
查看次数

TSaveDialog和2种具有相同扩展名的格式

在TSaveDialog中,我添加了两种具有相同扩展名的格式:

Format A|*.form
Format B|*.form
Format C|*.diff
Run Code Online (Sandbox Code Playgroud)

现在,我要确定用户选择的格式:

var Ext: String;
begin
  if not SaveDialog1.Execute then Exit;

  Ext := LowerCase(ExtractFileExt(SaveDialog1.FileName));
Run Code Online (Sandbox Code Playgroud)

这样我可以将“格式B”与“格式C”区分开来,但不能将“格式A”与“格式B”区分开。

delphi save-dialog tsavedialog

5
推荐指数
2
解决办法
120
查看次数

Access文本字段上的唯一索引是否始终不区分大小写?

我使用以下代码创建了MS Access表:

  tbl := Database.CreateTableDef('English', 0, '', '');
  try
    fld := tbl.CreateField('ID', dbLong, 0);
    fld.Attributes := dbAutoIncrField + dbFixedField;
    tbl.Fields.Append(fld);

    fld := tbl.CreateField('Content', dbText, 255);
    fld.Required := true;
    fld.AllowZeroLength := false;
    tbl.Fields.Append(fld);

    Database.TableDefs.Append(tbl);

    idx := tbl.CreateIndex('PrimaryKey');
    idx.Fields.Append(idx.CreateField('ID', EmptyParam, EmptyParam));
    idx.Primary := True;
    idx.Unique := true;
    tbl.Indexes.Append(idx);

    idx := tbl.CreateIndex('IX_Content');
    idx.Fields.Append(idx.CreateField('Content', EmptyParam, EmptyParam));
    idx.Primary := false;
    idx.Unique := true;
    tbl.Indexes.Append(idx);
  finally
    tbl := nil;
  end;
Run Code Online (Sandbox Code Playgroud)

这工作正常,直到我尝试将两个字符串'字段类型'和'字段类型'插入此表.我收到一个错误,告诉我唯一的索引限制我这样做.正如您所看到的,它们仅在第二个单词的情况下有所不同.由于我没有明确地使索引不敏感(我甚至不知道如何做),我不太明白为什么会发生这种情况.文本字段中的索引在MS Access中是否始终不区分大小写?如果没有,我做错了什么?

delphi indexing ms-access

4
推荐指数
1
解决办法
805
查看次数

如何在此RaiseExeption调用中删除"W1047 Unsafe code'@ operator'"

Delphi 2007中的以下代码给出了警告

W1047不安全代码'@ operator'

在将@ThreadNameInfo传递给RaiseException的行中:

procedure SetThreadName(const _Name: AnsiString);
var
  ThreadNameInfo: TThreadNameInfo;
begin
  ThreadNameInfo.FType := $1000;
  ThreadNameInfo.FName := PAnsiChar(_Name);
  ThreadNameInfo.FThreadID := $FFFFFFFF;
  ThreadNameInfo.FFlags := 0;
  try
    RaiseException($406D1388, 0, SizeOf(ThreadNameInfo) div SizeOf(LongWord),
      @ThreadNameInfo); // --> Here
  except
    // ignore
  end;
end;
Run Code Online (Sandbox Code Playgroud)

除了禁用"不安全代码"的编译器警告之外,还有其他方法可以摆脱此警告吗?这个警告是否更有意义,因为Delphi不再支持dotNET?

我试图明确地将参数类型转换为PDWord(最后一个参数的声明类型),它没有改变任何东西.

delphi delphi-2007

4
推荐指数
1
解决办法
480
查看次数