Jump to content

Primož Gabrijelčič

Members
  • Content Count

    217
  • Joined

  • Last visited

  • Days Won

    9

Primož Gabrijelčič last won the day on June 3

Primož Gabrijelčič had the most liked content!

Community Reputation

192 Excellent

5 Followers

Technical Information

  • Delphi-Version
    Delphi 10.2 Tokyo

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Primož Gabrijelčič

    Omnithread DELPHI, many calls in the same function

    This is actually a COM problem, I believe, and I know almost nothing about COM, so please consider that my thinking may be entirely wrong. I believe that you are having problems because you initialize your server in tmApartment mode but then access it from multiple threads. http://docwiki.embarcadero.com/RADStudio/Sydney/en/Choosing_a_Threading_Model says for tmApartment: " All client calls use the thread in which the object was created." And the object is created in the main thread. Does your code work if you use TThread instead of OTL to run async tasks?
  2. Primož Gabrijelčič

    Omnithread DELPHI, many calls in the same function

    I'm very sorry but I really don't speak any Frech. Can you please translate your question?
  3. Primož Gabrijelčič

    Sample for TWaitFor (or something similar)

    For Synchronize mechanism to work, console application should be calling function CheckSynchronize from System.Classes repeatedly. You can do that from the message processing loop.
  4. Primož Gabrijelčič

    Sample for TWaitFor (or something similar)

    If Synchronize is not working (can't tell why without your code), use Queue with a record containing (data, result, flag) and wait for main thread to set the flag. Like this: var res, data: ... flag: boolean; flag := false; TThread.Queue(nil, procedure begin res := Process(data); flag := true; end); while not flag do Sleep(0); Or make 'flag' an event and wait on it.
  5. Primož Gabrijelčič

    Understanding UniqueFilter stage from WebSpider demo

    Indeed. IOmniBlockingCollection implements an enumerator which waits for the next available value. The only way to terminate such for loop is to call input.CompleteAdding which signals the enumerator that no new values can ever be produced.
  6. Primož Gabrijelčič

    Adding call to sleep blocks stage in pipeline

    SimplePipeline is, well, simple. This is the TButton event handler: procedure TfrmSimplePipeline.btnPipelineClick(Sender: TObject); var pipeline: IOmniPipeline; i: Integer; v: TOmniValue; begin pipeline := Parallel.Pipeline; pipeline.Stage(AddOne); pipeline.Stage(Invert); pipeline.Run; for i := 1 to 5 do pipeline.Input.Add(i); pipeline.Input.CompleteAdding; for v in pipeline.Output do lbLog.Items.Add(Format('%.3f', [v.AsDouble])); pipeline := nil; end; As you can see, the code starts the pipeline and then runs the loop that processes the results. This loop is run in a main thread and therefore blocks the UI. If you slow down the pipeline, it needs more time to generate the results and UI is blocked.
  7. Primož Gabrijelčič

    Understanding UniqueFilter stage from WebSpider demo

    UniqueFilter does not go out of scope. If defined in this format (with input, output: IOmniBlockingCollection parameters), pipeline only calls it once. The 'for url in input' loop is the one that processes all elements that arrive via the input pipeline.
  8. Primož Gabrijelčič

    Sample for TWaitFor (or something similar)

    No, WaitFor is not the right choice. Just use TThread.Queue and execute the code in the main thread. Something like: res := CalculateTheResult(); TThread.Queue(nil, procedure begin // This procedure will execute in the main thread. // The address of the 'res' variable will be automatically captured so you can use its value here. ProcessInMainThread(res); end);
  9. Primož Gabrijelčič

    Stopping a TimedTask

    Can I get a minimal reproducible example project, please?
  10. Primož Gabrijelčič

    DSiWaitForTwoObjects

    Sorry, impossible to guess 😞 Would need a test app that shows that behaviour to say more.
  11. Primož Gabrijelčič

    DSiWaitForTwoObjects

    DSiWaitForTwoObjects is just a shortcut which calls WaitForMultipleObjects Windows API with two handles. In this case it will return with status WAIT_TIMEOUT when a timeout elapses, WAIT_OBJECT_1 when task.Comm.NewMessageEvent is signalled or WAIT_OBJECT_0 when task.TerminateEvent is signalled.
  12. Primož Gabrijelčič

    Parallel.For and Timer

    Parallel.For by default works in "blocking" mode. IOW, while the Parallel.For is being executed, owner thread (main thread in your case) does nothing else. Most importantly - it does not process messsages. There are two ways around this problem. Use the .NoWait qualifier: FFor := Parallel.For(...).TaskConfig(...).NumTasks(...).NoWait.Execute(...). (http://www.omnithreadlibrary.com/book/chap06.html#highlevel-for, section 3.11.1) Read here why you have to store the result of the Parallel.For call into a field: http://www.omnithreadlibrary.com/book/chap06.html#leanpub-auto-a-life-cycle-of-an-abstraction. Execute the Parallel.For asynchronously via Parallel.Async mechanism (http://www.omnithreadlibrary.com/book/chap06.html#highlevel-async): Parallel.Async( procedure begin Parallel.For....Execute(); end);
  13. Primož Gabrijelčič

    Task dies unexpectedly

    Your way of killing children is fine. It should not cause the behaviour you are observing.
  14. Primož Gabrijelčič

    Task dies unexpectedly

    If the OnTerminated is not called, then the task owner (MainTask) is not processing messages. If MainTask is an OTL task, then you can just call it's function MsgWait when you create it. MainTask := CreateTask(TOmniWorkerDescendant.Create()).MsgWait;
  15. Primož Gabrijelčič

    Task dies unexpectedly

    Missed that one, sorry. If a OnTerminated is not called (but is called when the task does not die), then the task is probably killed with TerminateThread somewhere.
×