Andy开发的这个Library AsynCalls让我印象深刻.
我写了一段代码只是为了测试库,但它总是得到内存A/V,我在这里想念一些东西吗?
以下代码旨在使用两个异步线程并行执行此简单任务(从数组中获取最大值).
program Test;
{$APPTYPE CONSOLE}
uses
SysUtils,
Math,
Windows,
Forms,
AsyncCalls in 'AsyncCalls.pas';
var
arr: array of integer;
i: integer;
procedure GetMax(const arr: array of integer; left, right: integer; var max: integer);
var
i: integer;
begin
max := arr[left];
for i := left + 1 to right do
begin
if (arr[i] > max) then
begin
max := arr[i];
end;
end;
end;
const
N = 100000;
var
a, b: IAsyncCall;
maxv, max1, max2: integer;
begin
SetLength(arr, N);
maxv := -1;
for i := 0 to High(arr) do
begin
arr[i] := RandomRange(0, MaxInt);
if (arr[i] > maxv) then
begin
maxv := arr[i];
end;
end;
a := AsyncCall(@GetMax, [arr, 0, Length(arr) div 2, max1]);
b := AsyncCall(@GetMax, [arr, (Length(arr) div 2) + 1, High(arr), max2]);
while (AsyncMultiSync([a, b], True, 10) = WAIT_TIMEOUT) do
begin
Application.ProcessMessages;
end;
Writeln(max1, ', ', max2, ', ', Max(max1, max2));
Writeln(maxv);
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
您正在尝试使用的变量参数版本AsyncCall
.该代码表示支持以下类型:
Supported types: Integer : Arg: Integer Boolean : Arg: Boolean Char : Arg: AnsiChar WideChar : Arg: WideChar Int64 : [const] Arg: Int64 Extended : [const] Arg: Extended Currency : [const] Arg: Currency String : [const] Arg: ShortString Pointer : [const] Arg: Pointer PChar : [const] Arg: PChar Object : [const] Arg: TObject Class : [const] Arg: TClass AnsiString : [const] Arg: AnsiString UnicodeString: [const] Arg: UnicodeString PWideChar : [const] Arg: PWideChar WideString : [const] Arg: WideString Interface : [const] Arg: IInterface Variant : const Arg: Variant
您的函数接收一个打开的数组参数和一个var
参数,两者都没有在上面的列表中找到.而且,该函数必须使用cdecl
调用约定.
以下是您的代码的一个版本:
program Test;
{$APPTYPE CONSOLE}
uses
SysUtils,
Math,
AsyncCalls in 'AsyncCalls.pas';
var
arr: array of integer;
procedure GetMax(left, right: integer; max: PInteger); cdecl;
var
i: integer;
begin
max^ := arr[left];
for i := left + 1 to right do
begin
if (arr[i] > max^) then
begin
max^ := arr[i];
end;
end;
end;
const
N = 100000;
var
a, b: IAsyncCall;
i, maxv, max1, max2: integer;
begin
SetLength(arr, N);
maxv := -1;
for i := 0 to High(arr) do
begin
arr[i] := RandomRange(0, MaxInt);
if (arr[i] > maxv) then
begin
maxv := arr[i];
end;
end;
a := AsyncCall(@GetMax, [0, Length(arr) div 2, @max1]);
b := AsyncCall(@GetMax, [(Length(arr) div 2) + 1, High(arr), @max2]);
AsyncMultiSync([a, b], True, INFINITE);
Writeln(max1, ', ', max2, ', ', Max(max1, max2));
Writeln(maxv);
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
请注意,我做了以下更改:
Forms
和调用ProcessMessages
.GetMax
使用cdecl
调用约定.max
作为指向整数而不是var
参数的指针传递.那是因为var
不支持参数.GetMax
使用全局变量arr
而不是接收它作为参数.这是为了权宜之计.另一种方法是传递第一个元素的地址.坦率地说,你的代码足够复杂,使变量参数AsyncCall
感觉有点拉长.您可能最好传递一个对象或一个指向记录的指针,而不是使用变量参数重载.
我还应该指出,不再开发AsyncCalls.在我看来,采用OTL而不是AsyncCalls会更好.
归档时间: |
|
查看次数: |
407 次 |
最近记录: |