views:

3055

answers:

6

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

+4  A: 

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).

PhiS
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.
mghie
@mghie - 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).
PhiS
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.
mghie
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.
Deltics
+1 Deltics. This is a sad, sorry state of affairs. What a piece of Crap TThread is.
Warren P
+10  A: 

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 http://wings-of-wind.com/2009/08/28/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.

RRUZ
This is great, except I'd like to know what code we actually need to write?
Warren P
+3  A: 

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.

Andrei K.
+3  A: 

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.

Deltics
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*.
mghie
There has been some discussion on Suspend/Resume here:http://forums.codegear.com/message.jspa?messageID=3466Especially 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.
PhiS
According to Allen Bauer, these functions are intended for use in debuggers which need to control thread state.
David Taylor
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 Suspend2) Properly documented the intended use of the methods.It's then up to the developer whether to use them or not.
Deltics
It really stinks that CodeGear/Embarcadero deprecated Suspend but did not introduce a replacement.
Warren P
+1  A: 

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.

Andriy Gerasika