View previous topic :: View next topic |
Author |
Message |
VoteFW
Joined: 08 Jul 2007 Posts: 4 Location: Lexington, MA
|
Posted: Tue Jul 10, 2007 6:22 pm Post subject: .NET ThreadStart Delegate |
|
|
I have been trying to convert a user application to FTN95 .NET, and am having a problem getting ThreadStart delegate coded properly. Following code works except the instantiation of the AppStart object.
! TDTM - .NET Test Program
! Namespace Name
MODULE UserApp
LIBRARY "System.dll"
LIBRARY "System.Data.dll"
LIBRARY "System.Drawing.dll"
LIBRARY "System.Windows.Forms.dll"
LIBRARY "SciPlot.dll"
ASSEMBLY_EXTERNAL(name="System.Console.ReadLine") ReadLine
ASSEMBLY_EXTERNAL(name="SciPlot.SP.EVTAPP") EVTAPP
ASSEMBLY_EXTERNAL(name="SciPlot.SPIde.IDEBEG") IDEBEG
ASSEMBLY_EXTERNAL(name="SciPlot.SPIde.IDERTN") IDERTN
! Class Fields
INTEGER(4):: IdeFlag
END MODULE UserApp
! User Application:
SUBROUTINE AppMain(Flag)
USE UserApp
IMPLICIT NONE
INTEGER(4) :: rtnsts,Flag
STRING :: line
OBJECT("System.Exception") se
OBJECT("System.Threading.ThreadAbortException") te
TRY
! Code will be added here......
IF (IdeFlag.EQ.0) THEN
line = ReadLine()
rtnsts = IDERTN(2)
END IF
IF (IdeFlag.EQ.1) THEN
rtnsts = IDERTN(0)
END IF
CATCH (te)
! User has pressed the "Halt" button
CATCH (se)
! Report exception in AppMain and terminate
CALL EVTAPP(se)
END TRY
END SUBROUTINE AppMain
! Main Program
PROGRAM MAIN
USE UserApp
IMPLICIT NONE
EXTERNAL AppMain
! Local variables definition
INTEGER(4) :: rtnsts
STRING :: line
OBJECT("System.Exception") se
OBJECT("SciPlot.SPIde") IdeForm
OBJECT("System.Threading.ThreadStart") AppStart
! SciPlot SPIde Class Instantiation
IdeFlag = 1
IF (IdeFlag.EQ.0) THEN
IdeForm = NEW@("SciPlot.SPIde",0)
END IF
IF (IdeFlag.EQ.1) THEN
IdeForm = NEW@("SciPlot.SPIde",1)
END IF
! Following fortran code fails to compile...
! AppStart = NEW@("System.Threading.ThreadStart",AppMain)
! Equivalent C# code
! public static ThreadStart AppStart = new ThreadStart(AppMain);
TRY
! Start SPIde Control Form
rtnsts = IDEBEG(AppStart)
STOP
CATCH (se)
! Report exception in Main Program
CALL EVTAPP(se)
ENDTRY
END PROGRAM
If anyone has an idea how to code it, please help me.
F Vote |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Wed Jul 11, 2007 7:07 am Post subject: |
|
|
I am not able to give a direct answer to your enquiry but here are some general points...
1. Have you tried using CREATE_THREAD@ etc as described in the help file under .NET platform->.NET Programming->Threads?
2. For multi-threading you need the DBK_LINK command line option /MULTI_THREADED. This option is also available with FTN95 but only has any effect when used with /LINK because it is simply passed on to DBK_LINK.
3. If you think that FTN95 is not doing what it should then it is a good idea to post a complete short program that illustrates the problem so that we can try it out for you. |
|
Back to top |
|
|
VoteFW
Joined: 08 Jul 2007 Posts: 4 Location: Lexington, MA
|
Posted: Wed Jul 11, 2007 4:40 pm Post subject: .NET ThreadStart Delegate |
|
|
Unfortunately, CREATE_THREAD@ creates a thread and starts it. I need to start the thread at a much later time, and so need to create a ThreadStart delegate that is initialized with the app to be started.
The problem I described only involves the FTN95 compiler, not the linker.
The "Threads" FTN95 documentation states "Althought it is possible to create and start a thread using calls to the .NET framework" . This is why I assumed I could use a ThreadStart delegate.
I will take your suggestion and attempt a very short and simple program to demonstrate the FTN95 compiler's handling of the ThreadStart delegate.
Thaks for the reply |
|
Back to top |
|
|
VoteFW
Joined: 08 Jul 2007 Posts: 4 Location: Lexington, MA
|
Posted: Wed Jul 11, 2007 5:32 pm Post subject: |
|
|
Paul,
Here is the short program which fails to compile:
MODULE UserApp
LIBRARY "System.dll"
LIBRARY "System.Data.dll"
LIBRARY "System.Drawing.dll"
LIBRARY "System.Windows.Forms.dll"
ASSEMBLY_EXTERNAL(name="System.Console.WriteLine") WriteLine
END MODULE UserApp
SUBROUTINE AppMain(AppStart)
USE UserApp
IMPLICIT NONE
OBJECT("System.Exception") se
OBJECT("System.Threading.ThreadStart") AppStart
TRY
CALL WriteLIne(" AppMain Entered")
CATCH (se)
CALL WriteLine(" Exception in AppMain")
END TRY
END SUBROUTINE AppMain
PROGRAM MAIN
USE UserApp
IMPLICIT NONE
EXTERNAL AppMain
INTEGER(4) :: rtnsts
STRING :: line
OBJECT("System.Exception") se
OBJECT("SciPlot.SPIde") IdeForm
OBJECT("System.Threading.ThreadStart") AppStart
! FTN95 fails to compile this code correctly
AppStart = NEW@("System.Threading.ThreadStart",AppMain)
! Equivalent C# code
! public static ThreadStart AppStart = new ThreadStart(AppMain);
TRY
CALL AppMain(AppStart)
STOP
CATCH (se)
CALL WriteLine(" Exception in Main Program")
ENDTRY
END PROGRAM
Thanks for looking at it.
Fred Vote |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Thu Jul 12, 2007 7:38 am Post subject: |
|
|
I have not had chance to look at your code yet but here are some observations.
A delegate is equivalent in many ways to a function. The thread delegate is effectively the function that the thread runs to execute the process. Hence it is defined in the code. When you start a thread the delegate (thread function) is called.
In the Windows API you can use CreateThread to start a thread in a paused state but I cannot see the equivalent of this in .NET. There is Threading.Suspend but this is depreciated.
I suspect that for simplicity you should be using CREATE_THREAD@ and or CREATE_THREAD1@. Given time I guess I could work out how to do the same thing by using a Threading.Thread constructor but the result would be the same.
On the other hand I may be missing the point altogether. |
|
Back to top |
|
|
VoteFW
Joined: 08 Jul 2007 Posts: 4 Location: Lexington, MA
|
Posted: Thu Jul 12, 2007 1:14 pm Post subject: .NET ThreadStart Delegate |
|
|
The point is: instantiating the StartThread object in the Fortran code allows it to be passed to a C# DLL as an argument. That C# DLL can then create an AppMain thread at any time, start it, and when it terminates (terminated threads cannot be started a second time), create another AppMain thread, and start it again at any time (on a button press). CREATE_THREAD@ forces all this control to happen right in the Fortran code. This is not where my application does it. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Fri Jul 13, 2007 2:52 pm Post subject: |
|
|
As far as I can tell, what you are attempting is not possible because the delegate is a .NET object and you cannot match this with a Fortran subprogram. You can do something like this from C# but only in very limited way as illustrated by the callback functions in Visual ClearWin.
Here is my trial code which goes part of the way but fails to compile even before trying to match a delegate...
ASSEMBLY_EXTERNAL(NAME="System.Threading.Thread.Start") ThreadStart
OBJECT("System.Threading.ThreadStart") threadDelegate
OBJECT("System.Threading.Thread") newThread
OBJECT("System.Object") workFunction
workFunction = NEW@("System.Object")
threadDelegate = NEW@("System.Threading.ThreadStart", workFunction)
newThread = NEW@("System.Threading.Thread", threadDelegate)
CALL ThreadStart(newThread)
You could try experimenting with this but my guess is that it is not going to work. FTN95 is not designed to handle this level of sophistication. |
|
Back to top |
|
|
|