TThread.resume is deprecated in Delphi-2010 what should be used in place?
Asked Answered
D

8

37

In my multithread application

I use TThread.suspend and TThread.resume

Since moving my application to Delphi 2010 I get the following warring message

[DCC Warning] xxx.pas(277): W1000 Symbol ‘Resume’ is deprecated

If Resume is deprecated what should be used in place?

EDIT 1:

I use the Resume command to start the thread - as it is Created with 'CreateSuspended' set to True and Suspend before I terminate the thread.

EDIT 2:

Here is a link the delphi 2010 manual

Darmstadt answered 13/9, 2009 at 17:39 Comment(0)
N
30

Charles if do you read the code of TThread class , do you find the answer.

   TThread = class  
   private type  

..
..
..   
   public  
     constructor Create(CreateSuspended: Boolean);  
     destructor Destroy; override;  
     procedure AfterConstruction; override;  
     // This function is not intended to be used for thread synchronization.  
     procedure Resume; deprecated;  
     // Use Start after creating a suspended thread.  
     procedure Start;  
     // This function is not intended to be used for thread synchronization.  
     procedure Suspend; deprecated;  
     procedure Terminate;  

See this link RAD Studio 2010: Community pulse: The day after. (Part 2)

Edit:

If you need to synchronize threads, you can use a scheme based on TMutex, TEvent and critical sections.

Bye.

Nudi answered 13/9, 2009 at 18:2 Comment(3)
This is great, except I'd like to know what code we actually need to write?Singlefoot
link is not working. Now its content is on windwings.wordpress.com/2009/08/28/…Adamik
Not everyone has access to the RTL code within their Delphi install.Morphology
I
14

Use TThread.Start instead of .Resume

--EDIT-- Start can of course only be used with Delphi 2010 (and later, presumably) to start a thread that was created suspended (where you would have used Resume before).

Using Resume/Suspend (or corresponding WinAPI functions) for thread synchronisation is NOT recommended. See the discussion here (have a look at Barry Kelly's comments).

Impostume answered 13/9, 2009 at 17:49 Comment(5)
Not an answer, really - using Suspend() and Resume() for "synchronization" has been deprecated without any replacement. Proper synchronization objects have been available since the time of Delphi 2. And it's high time these ill-conceived methods were deprecated.Teplica
@Teplica - Agreed, Suspend/Resume should not be used for synchronisation, but synchronisation is nowhere mentioned in the question. And the new "Start" can replace the old "Resume" at least in some cases (cf. the TThread code posted by RRUZ).Impostume
I agree as far as Resume() goes. However with Suspend() there's IMO only this explanation, even when it isn't spelled out in the question.Teplica
Start can replace Resume only if you aren't sharing source code with developers who are (potentially) using older versions of Delphi. imho Suspend should have been deprecated and Resume adequately documented. e.g "Resume is intended to be used to activate a thread created in an initially suspended state. Suspend and Resume should not be used to manage the execution state of a thread once it has started running. Better yet, Suspend should have been fixed (if it hasn't already) and left NOT deprecated, but some decent documentation put in place.Cheriecherilyn
+1 Deltics. This is a sad, sorry state of affairs. What a piece of Crap TThread is.Singlefoot
C
7

Suspend and Resume were (or used to be) potentially broken in the TThread class (if you look at the source you will see that the Suspend method directly and unconditionally sets a Boolean to indicated thread suspended state rather than more robustly deriving this state from the execution count on the thread handle. Ironically the Resume method does use this more robust indicator to update the suspended state Boolean).

This is possibly why they have been deprecated. It's also why I implemented my own class to encapsulate a Windows thread with a more robust suspend and resume mechanism as well as the ability to Restart a thread once it had completed.

I'm not sure why their deprecation is supposedly related to synchronization. Suspending and resuming threads is not necessarily related to synchronization, although I can see how it might be. It's interesting to note that the equivalent methods in the .NET framework Thread class are similarly marked as obsoleted. And the same comments w.r.t synchronization appear in the Windows API documentation for thread suspend/resume.

If using deprecated methods makes you nervous and you still wish to suspend/resume you could always use the Windows API to suspend and resume the thread by reference to it's handle.

Cheriecherilyn answered 13/9, 2009 at 20:55 Comment(7)
Could you add some information what Suspend() and Resume() should in your opinion be used for, if "suspending and resuming threads is not necessarily related to synchronization"? I also really do wonder why a thread would ever have to be restarted.Teplica
There has been some discussion on Suspend/Resume here: forums.codegear.com/message.jspa?messageID=3466 Especially have a look at Barry Kelly's comments. The bottom line is that you shouldn't touch Suspend or the WinAPI SuspendThread functions, and Resume should essentially only be used for starting a thread that was created suspended. Suspend/Resume should not be used for thread synchronisation.Impostume
According to Allen Bauer, these functions are intended for use in debuggers which need to control thread state.Augmenter
A mistake imho. Suspending and Resuming a thread is a legitimate operation. It's not the correct way to do certain things, but explaining how/when to use something properly is what documentation is for. Rather than deprecating and hoping that people will simply stop using the methods (relying on vague "do not use these methods for synchronization" and google to help people understand why) they should have: 1) Fixed the implementation of Suspend 2) Properly documented the intended use of the methods. It's then up to the developer whether to use them or not.Cheriecherilyn
It really stinks that CodeGear/Embarcadero deprecated Suspend but did not introduce a replacement.Singlefoot
@Deltics: Dead wrong here. Suspending a thread is not legitimate if you're not a debugger. From SuspendThread: "Calling SuspendThread on a thread that owns a synchronization object, such as a mutex or critical section, can lead to a deadlock if the calling thread tries to obtain a synchronization object owned by a suspended thread." ----- example: the worker thread you are suspending was in the middle of a call to malloc, and the allocator has locked the heap. Now your main thread, which suspended the worker thread, will also "suspend" (i.e. deadlock) next time it calls malloc.Methodius
@James - Dead wrong how ? I say it is legitimate. One situation where it is legitimate is when you are a debugger. You say the exact same thing using different words. What's missing is any reference to this fact or the concrete examples of potential for error, in the documentation. Of course, if a thread does not own synchronization objects (directly or indirectly) then your deadlock scenario is utterly irrelevant. Which doesn't alter the fact that you shouldn't ordinarily use Suspend/Resume, or that the reasons why not are still not explained in the docs. Which is all I said.Cheriecherilyn
T
5

Just in case all you wanted to do was get rid of the compiler hints

(1) To get rid of the compiler hint when Starting a Thread ...

replace

MyThread := TMyThread.Create(True);
MyThread.Resume;

with

MyThread := TMyThread.Create(True);
MyThread.Start;

(2) To get rid of the compiler hint when Stopping a Thread ...

replace

MyThread.Suspend;
MyThread.Terminate;

with

MyThread.Terminate;

Not a big deal at all. Beware of attempted obfuscation.

Thrift answered 29/7, 2013 at 5:33 Comment(0)
O
5

Use

Suspended := False; // Resume;

or

Start;
Othelia answered 24/9, 2013 at 6:21 Comment(1)
This is what I have been looking for! A way to pause the thread and resume It at any moment In time.Antiicer
K
4

Thread behavior control code should lie with in a thread procedure. Use appropriate sync objects and corresponding API calls in order to suspend/resume thread execution. Doing it from outside is a dangerous practice. So there was a decision to depricate it.

Kithara answered 13/9, 2009 at 18:55 Comment(1)
Agreed. This is good sense, as far as it goes, however writing it yourself every time is like having to weld something on your car every time you want to parallel park it. A basic service like "a worker thread that can be paused" should at least be part of a TWorkerThread, if not in the base TThread itself.Singlefoot
G
3

You should create the thread as follows:

constructor TSignalThread.Create;
begin
 // create event handle first!
  FEventHandle := CreateEvent(
          {security}      nil,
          {bManualReset}  true,
          {bInitialState} false,
          {name}          nil);
  FWaitTime := 10;
  inherited Create({CreateSuspended}false);
end;

This way a call to Start is not required.

See http://www.gerixsoft.com/blog/delphi/creating-threads for an explanation why this code works.

Ginni answered 3/7, 2010 at 15:55 Comment(0)
P
2

@mghie (a little late, I know)

take for example madexcept and alike. If your application crashes and a bug report is being shown to user, that means that the dialog waits for use input. If it so happens that the crash is a result of a thread action (not necessarily a thread crashing), if you do not suspend the threads, the screen will be filled with bug report dialogs.

example 2: logging. for any particular reason, I at least, had the need to log some threads execution state. That includes the current stack trace. Now, as you (should) know, you cannot do that while the thread is running because during the time you collect information about it, the threads keeps doing stuff so by the time you finish collection, the information collected will not be consistent. Hence, you need to suspend the thread.

And I can go on with practical examples on thread management. Granted, these are not things you do in every day programming, but at least the first example I am sure that many of you are using, even if you are not aware of the internals of it. Debuggers? again, you use them. But indeed, in all these cases, TThread is not used, since the work is done on thread handles. So, indeed, a valid example of TThread suspend usage is hard to come by. But threads in general, that's another story.

Pneumatic answered 1/3, 2011 at 8:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.