标签: omnithreadlibrary

多线程WinHttp下载

我正在创建一个Delphi应用程序来从Internet下载文件,如果服务器支持范围请求它将是多线程的.进度也被转发回GUI.

当前的软件模型使用TThread组件.GUI调用a TDownloadThread然后生成TDownloadPartThreads- 这些是实际通过'WinHttp'进行下载的线程.

我的问题:CPU已用完,即使只下载4个线程的下载.

我的假设原因:

  1. 我每8192字节写一次目标文件,想知道在写入一个块之前是否应该缓冲它?
  2. 线程通信是通过Synchronize(MainForm.UpdateProgress(Downloaded, TotalSize))我听到的AWFUL来完成的,也许我应该在线程之间共享一个对象,这样我可以使用主窗体上的计时器来访问它,以更新进度?

我的解决方案

  1. 交错文件写入只写每个x字节.

  2. 更新TThread要使用的组件,OmniThreadLibrary并以某种方式将数据发送回主表单.TDownloadPart然后,每个线程将成为一个IOmniWorker并通过与主表单共享对象来发回其进度.然后,主窗体将使用计时器来更新其进度,如:ProgressBar1.Position := sharedDataObject.Progress;

希望有人可以指出我正确的方向!

delphi multithreading winhttp omnithreadlibrary

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

在线程中使用datasnap ServerMethod返回的DataSet?

我使用Omnithreadlibrary从一个线程中调用一个服务器方法,数据成功返回,但我使用返回的数据有麻烦,我尝试的一切都与AccessViolation或应用程序崩溃,尝试也设置数据集在一个链接到ClientDataSet的DataSetProvider,但是这里它也不起作用,最后我设置服务器方法返回OleVariant并将其直接设置为ClientDataSet的Data属性,但我也有错误.

我的目的是让请求在一个线程中完成,并将数据返回到主线程中的函数来填充网格.

有什么建议?

delphi dataset datasnap omnithreadlibrary

5
推荐指数
0
解决办法
1095
查看次数

如何使用Delphi和OmniThread将文件上传到背景中?

我试图用Delphi将+100文件上传到azure.但是,调用会阻塞主线程,因此我想通过异步调用或后台线程来执行此操作.

这就是我现在所做的事情(如此处所述):

procedure TCloudManager.UploadTask(const input: TOmniValue;
  var output: TOmniValue);
var
  FileTask:TFileTask;
begin
  FileTask := input.AsRecord<TFileTask>;

  Upload(FileTask.BaseFolder, FileTask.LocalFile, FileTask.CloudFile);
end;

function TCloudManager.MassiveUpload(const BaseFolder: String;
  Files: TDictionary<String, String>): TStringList;
var
  pipeline: IOmniPipeline;
  FileInfo : TPair<String,String>;
  FileTask:TFileTask;
begin
  // set up pipeline
  pipeline := Parallel.Pipeline
    .Stage(UploadTask)
    .NumTasks(Environment.Process.Affinity.Count * 2)
    .Run;
  // insert URLs to be retrieved
  for FileInfo in Files do
  begin
    FileTask.LocalFile := FileInfo.Key;
    FileTask.CloudFile := FileInfo.Value;
    FileTask.BaseFolder := BaseFolder;

    pipeline.Input.Add(TOmniValue.FromRecord(FileTask));
  end;//for

  pipeline.Input.CompleteAdding;

  // wait for pipeline to complete
  pipeline.WaitFor(INFINITE); …
Run Code Online (Sandbox Code Playgroud)

delphi multithreading azure delphi-xe2 omnithreadlibrary

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

如何用OmniThreadLibrary替换TThread?

我习惯于创建TThread后代来进行长时间的数据库操作.我通常的构造看起来像这样:

interface
type
  TMyDBOp = class(TThread)
  private
    FConnection: TADOConnection;
    FCommand1: TADOCommand;
    FCommand2: TADOCommand; // and many more privated objects, vars ...
    procedure InitDB;
    procedure DoneDB;
    procedure DoDBStuff; // and many more procedures and functions to structure the code
  protected
    procedure Execute; override;
  public
    constructor Create; reintroduce;
    property X: T... // and many more properties to set on thread creation
  end;

implementation

constructor TMyDBOp.Create;
begin
  inherited Create(False);
end;

procedure TMyDBOp.InitDB;
begin
  FConnection:= TADOConnection.Create(nil);
  // setup all connection props, setup all other …
Run Code Online (Sandbox Code Playgroud)

delphi omnithreadlibrary

5
推荐指数
0
解决办法
667
查看次数

Delphi 2010中其他线程的执行点

我正在使用Delphi 2010开发一个多线程客户端应用程序(使用优秀的OmniThreadLibrary),因为我经常从一个线程交换到另一个线程,所以我很难进行调试.

我想知道是否有可能(使用任何工具或插件,我不在乎!)找到当前执行点,不仅是当前线程,还有所有其他线程.

一个简单的例子/报告:

Thread #1 stopped at line #5
Thread #2 stopped at line #25 (<-- breakpoint set here, causing Delphi to stop)
Thread #3 stopped at line #78
Run Code Online (Sandbox Code Playgroud)

我的目标是"看到"当Delphi在某个断点处停止时其他线程正在做什么,而不仅仅是使用日志(或者不那么有用的Thread 12345停止),而是检查它们就好像断点停在它们处.

我希望我的问题很清楚,请注意它已经过了午夜,所以如果我的问题听起来很愚蠢,请不要怪我!

delphi debugging multithreading omnithreadlibrary

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

如何监控OmniThreadLibrary中的Pipeline阶段?

是否有可能以某种方式监控管道任务?我试图像这样为每个任务添加监视器

FPipeline := Parallel.Pipeline()
  .Stage(StageWorker1, Parallel.TaskConfig.MonitorWith(MyMonitor))
     .NumTasks(MaxReadThreadCount)
  .Stage(StageWorker2, Parallel.TaskConfig.MonitorWith(MyMonitor))
  .Run();
Run Code Online (Sandbox Code Playgroud)

但获得异常"任务只能用一个监视器监视"(据我所知,这是因为已经为管道阶段安装了内部隐藏监视器).

delphi omnithreadlibrary delphi-xe4

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

我可以使用 OTL 来并行化嵌套循环吗?

我想知道我是否可以使用 OTL 来并行化这个循环。

我有以下代码。

for i := 1 to XRes do
 begin
   for j := 1 to XRes do
     begin
       GridMat.Elem[i,j] := StrToFloat(ListOfValues[(i-1)+((j-1)*Xres)]);
     end;
   Invalidate;
 end;
Run Code Online (Sandbox Code Playgroud)

是否可以将 GridMat(来自 SDL_matrix.TMatrix)作为参数传递给所有并行 ForEach 并将值添加到它。

delphi omnithreadlibrary

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

将监视器设置为dll中的任务时出现错误"只能使用单个监视器监视任务"

我在我的dll中使用OmniThreadLibrary 2.09,主应用程序和dll使用相同的SimpleShareMem内存管理器.

我用这段代码创建了自己的监视器:

  FMonitor: TOmniEventMonitor;
  ...
  FMonitor := TOmniEventMonitor.Create(nil);
Run Code Online (Sandbox Code Playgroud)

当我尝试使用此监视器创建新任务时,我收到错误"只能使用单个监视器监视任务"

FTask := OtlTaskControl.CreateTask(TaskWorker)
  .OnMessage(
    procedure(const ATaskControl: IOmniTaskControl; const AMsg: TOmniMessage)
    begin
      ...
    end)
  .MonitorWith(FMonitor)  //  <----- Error
  .OnTerminated(
    procedure (const ATaskControl: IOmniTaskControl)
    begin
      ...
    end)
  .Run();
Run Code Online (Sandbox Code Playgroud)

如何使用自己的显示器监控我的任务?

delphi dll omnithreadlibrary delphi-xe4

3
推荐指数
1
解决办法
153
查看次数

Delphi - Omnithreadlibrary,控制台应用程序中主线程的死亡

我在控制台应用程序中的BackgroundWorker(高级OmniThreadLibrary组件)中的主线程有问题.主线程(整个应用程序)中的对象在为后台任务调度WorkItems后立即死亡.主线程不等待OnRequestDone方法调用.

procedure TEntityIndexer.StartReindex;
begin
  if LoadTable then
    // in ProcessRecords method I schedule WorkItems for BackgroundWorker
      ProcessRecords;
  // when ProcessRecords method is done, application is at the end and
  // main thread is destoryed, so object in main thread is destroyed
  // and BackgroundWorker in object in main thread is destroyed too
end;

procedure TEntityIndexer.ProcessRecords;
var
  _id: Integer;
  _omniValue: TOmniValue;
begin
  FVTable.First;
  while not FVTable.Eof do
  begin
    _id := FVTable.FieldByName('record_id').AsInteger;
    WriteLogText(cProcesIndexLog, 'ID=' + IntToStr(_id) + '....PROCESS STARTED');

    _omniValue := TOmniValue.CreateNamed( …
Run Code Online (Sandbox Code Playgroud)

delphi multithreading console-application omnithreadlibrary

3
推荐指数
1
解决办法
230
查看次数

主线程阻塞并行线程?

创建一个VCL表单应用程序,在表单上放置一个TButton和一个TMemo,并在按钮的OnClick处理程序中编写此代码:

uses
  OtlParallel, OtlTaskControl;

procedure TForm2.btnStartLoopClick(Sender: TObject);
var
  starttime: Cardinal;
  k: Integer;
begin
  mmoTest.Lines.Clear;
  for k := 1 to 50 do
    mmoTest.Lines.Add('Line ' + IntToStr(k));

  starttime := GetTickCount;
  Parallel.Async(
    procedure
    var
      i: Integer;
    begin
      for i := 1 to 50 do
      begin
        Sleep(100);
        mmoTest.Lines[i - 1] := mmoTest.Lines[i - 1] + FormatDateTime(' nn:ss:zzz', Now);
      end;
    end,
    Parallel.TaskConfig.SetPriority(TOTLThreadPriority.tpHighest).OnTerminated(
    procedure
    begin
      mmoTest.Lines.Add(IntToStr(GetTickCount - starttime) + ' milliseconds');
    end));
end;
Run Code Online (Sandbox Code Playgroud)

现在运行程序并进行此测试:

  1. 单击按钮,只需等待循环完成并查看备忘录最后一行中显示的时间:它应该是大约5300毫秒.

  2. 现在再次单击按钮,单击并按住表单的标题栏并快速移动表单,直到循环结束.现在再看一下备忘录的最后一行:在我的测试中,时间超过7000毫秒.显然,主线程是阻塞并行线程!

那么如何避免阻塞并行线程的主线程呢?

delphi multithreading omnithreadlibrary delphi-10.1-berlin

3
推荐指数
1
解决办法
390
查看次数