Results 1 to 26 of 26

Thread: Asynchronous Open and Close of COM port

  1. #1

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Asynchronous Open and Close of COM port

    OK Here is an Asynchronous way to do it. I did not put the Class in a DLL or EXE. Just inside the project which may be the best option for you after all

    I wrote alot of this stuff years ago, but I just tested the project and it all works. Add the MODs, CLS, and the BAS files to your project.

    VB Code:
    1. Option Explicit
    2. '
    3. ' frm_COM_Test.frm
    4. '
    5. Private WithEvents m_COMPort As cls_COMPort
    6. '
    7.  
    8. Private Sub Form_Load()
    9.     Set m_COMPort = New cls_COMPort
    10. End Sub
    11.  
    12. Private Sub cmd_OpenPort_Click()
    13.     If (Not m_COMPort.OpenPort) Then
    14.         Me.Caption = "Open Port Unsuccessful"
    15.     Else
    16.         Me.Caption = "Open Port Successful"
    17.     End If
    18. End Sub
    19.  
    20. Private Sub cmd_ClosePort_Click()
    21.     '
    22.     Dim intReturn As Integer
    23.     intReturn = m_COMPort.ClosePort
    24.     '
    25.     If Not (intReturn = 0) Then
    26.         Me.Caption = "Can't Close Port: " & intReturn
    27.     Else
    28.         Me.Caption = "Close Port Successful"
    29.     End If
    30.     '
    31. End Sub
    32.  
    33. Private Sub cmd_OpenAsync_Click()
    34.     m_COMPort.OpenPort_Async
    35. End Sub
    36.  
    37. Private Sub cmd_CloseAsync_Click()
    38.     m_COMPort.ClosePort_Async
    39. End Sub
    40.  
    41. Private Sub m_COMPort_PortCloseDone(intSuccessful As Integer)
    42.     '
    43.     If Not (intSuccessful = 0) Then
    44.         Me.Caption = "Can't Close Port: " & intSuccessful
    45.     Else
    46.         Me.Caption = "Close Port Successful"
    47.     End If
    48.     '
    49. End Sub
    50.  
    51. Private Sub m_COMPort_PortOpenDone(blnSuccessful As Boolean)
    52.     If (Not blnSuccessful) Then
    53.         Me.Caption = "Open Port Unsuccessful"
    54.     Else
    55.         Me.Caption = "Open Port Successful"
    56.     End If
    57. End Sub

    VB Code:
    1. Option Explicit
    2. '
    3. ' VB Module: mod_ComTest.bas
    4. '
    5. Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
    6.     (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
    7.     ByVal dwShareMode As Long, lpSecurityAttributes As Any, _
    8.     ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
    9.     ByVal hTemplateFile As Long) As Long
    10. '
    11. '// This is the declaration to close the COM port
    12. Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    13. '

    VB Code:
    1. Option Explicit
    2. '
    3. ' VB Module: modTimers.bas
    4. '
    5. Private Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
    6. Private Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
    7. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
    8. '
    9. Private mcolItems   As Collection
    10. '
    11.  
    12. Public Sub AddTimer(ByRef pobjTimer As APITimer, ByVal plngInterval As Long)
    13.     If mcolItems Is Nothing Then
    14.         Set mcolItems = New Collection
    15.     End If
    16.     pobjTimer.ID = SetTimer(0, 0, plngInterval, AddressOf Timer_CBK)
    17.     mcolItems.Add ObjPtr(pobjTimer), pobjTimer.ID & "K"
    18. End Sub
    19.  
    20. Public Sub RemoveTimer(ByRef pobjTimer As APITimer)
    21. On Error GoTo ErrHandler
    22.     mcolItems.Remove pobjTimer.ID & "K"
    23.     KillTimer 0, pobjTimer.ID
    24.     pobjTimer.ID = 0
    25.     If mcolItems.Count = 0 Then
    26.         Set mcolItems = Nothing
    27.     End If
    28.     Exit Sub
    29. ErrHandler:
    30.    
    31. End Sub
    32.  
    33. Public Sub Timer_CBK(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal SysTime As Long)
    34. Dim lngPointer  As Long
    35. Dim objTimer    As APITimer
    36. On Error GoTo ErrHandler
    37.     lngPointer = mcolItems.Item(idEvent & "K")
    38.     Set objTimer = PtrObj(lngPointer)
    39.     objTimer.RaiseTimerEvent
    40.     Set objTimer = Nothing
    41.     Exit Sub
    42. ErrHandler:
    43.  
    44. End Sub
    45.  
    46. Private Function PtrObj(ByVal Pointer As Long) As Object
    47. Dim objObject   As Object
    48.     CopyMemory objObject, Pointer, 4&
    49.     Set PtrObj = objObject
    50.     CopyMemory objObject, 0&, 4&
    51. End Function

    VB Code:
    1. Option Explicit
    2. '
    3. ' <APITimer.cls>
    4. '
    5. ' References:
    6. '
    7. '   - modTimers.bas
    8. '
    9. '
    10. Public Event Refresh()
    11. '
    12. Private mlngTimerID As Long
    13. '
    14.  
    15. Friend Property Let ID(ByVal plngValue As Long)
    16.     mlngTimerID = plngValue
    17. End Property
    18.  
    19. Friend Property Get ID() As Long
    20.     ID = mlngTimerID
    21. End Property
    22.  
    23. Public Sub StartTimer(ByVal Interval As Long)
    24.     If mlngTimerID = 0 Then
    25.         AddTimer Me, Interval
    26.     End If
    27. End Sub
    28.  
    29. Public Sub StopTimer()
    30.     If mlngTimerID > 0 Then
    31.         RemoveTimer Me
    32.     End If
    33. End Sub
    34.  
    35. Private Sub Class_Terminate()
    36.     StopTimer
    37. End Sub
    38.  
    39. Friend Sub RaiseTimerEvent()
    40.     RaiseEvent Refresh
    41. End Sub

    VB Code:
    1. Option Explicit
    2. '
    3. ' Class: cls_COMPort.cls
    4. '
    5. Public Event PortOpenDone(blnSuccessful As Boolean)
    6. Public Event PortCloseDone(intSuccessful As Integer)
    7. '
    8. Private Const GENERIC_READ = &H80000000
    9. Private Const GENERIC_WRITE = &H40000000
    10. Private Const FILE_FLAG_OVERLAPPED = &H40000000
    11. Private Const OPEN_EXISTING = 3
    12. '
    13. Private m_lngFileHandle As Long
    14. '
    15. Private WithEvents m_OpenTimer As CountDownTimer
    16. Private WithEvents m_CloseTimer As CountDownTimer
    17. '
    18.  
    19. Public Sub OpenPort_Async()
    20.     '
    21.     ' Asynchronous way to Open the COM port
    22.     '
    23.     Set m_OpenTimer = New CountDownTimer
    24.     m_OpenTimer.Interval = 100
    25.     m_OpenTimer.Increment
    26. End Sub
    27.  
    28. Public Sub ClosePort_Async()
    29.     '
    30.     ' Asynchronous way to Close the COM port
    31.     '
    32.     Set m_CloseTimer = New CountDownTimer
    33.     m_CloseTimer.Interval = 100
    34.     m_CloseTimer.Increment
    35. End Sub
    36.  
    37. Private Sub m_CloseTimer_Finsihed()
    38.     '
    39.     Dim intReturn As Integer
    40.     '
    41.     intReturn = ClosePort
    42.     RaiseEvent PortCloseDone(intReturn)
    43.     '
    44. End Sub
    45.  
    46. Private Sub m_OpenTimer_Finsihed()
    47.     '
    48.     Dim blnReturn As Boolean
    49.     '
    50.     blnReturn = OpenPort
    51.     RaiseEvent PortOpenDone(blnReturn)
    52.     '
    53. End Sub
    54.  
    55. Public Function OpenPort() As Boolean
    56.     '
    57.     ' Synchronous way to Open the COM port
    58.     '
    59.     m_lngFileHandle = CreateFile("\\.\COM1", GENERIC_READ Or GENERIC_WRITE, 0, ByVal 0&, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)
    60.     '
    61.     If m_lngFileHandle > 0 Then
    62.         OpenPort = True
    63.     End If
    64.     '
    65. End Function
    66.  
    67. Public Function ClosePort() As Integer
    68.     '
    69.     ' Synchronous way to Close the COM port
    70.     '
    71.     If CloseHandle(m_lngFileHandle) <> 0 Then
    72.         ClosePort = 0
    73.     Else
    74.         ClosePort = Err.LastDllError
    75.     End If
    76.     '
    77. End Function
    78.  
    79. Public Property Get FileHandle() As Long
    80.     FileHandle = m_lngFileHandle
    81. End Property

    VB Code:
    1. Option Explicit
    2. '
    3. ' <CountDownTimer.cls>
    4. '
    5. ' Author: Dave Sell
    6. '
    7. ' References:
    8. '
    9. '   - APITimer.cls
    10. '   - modTimers.bas
    11. '
    12. ' Notes:
    13. '
    14. '   - Intervals are in ms
    15. '
    16. Public Event Refresh()
    17. Public Event Finsihed()
    18. Public Event Started()
    19. '
    20. Private WithEvents m_Timer As APITimer
    21. '
    22. Private m_CountDownInterval As Long
    23. Private m_ActiveIntervals As Long
    24. Private m_blnRunning As Boolean
    25. '
    26.  
    27. Public Sub Reset()
    28.     Set m_Timer = New APITimer
    29.     m_ActiveIntervals = 0
    30.     m_blnRunning = False
    31. End Sub
    32.  
    33. Private Sub Class_Initialize()
    34.     Reset
    35.     m_CountDownInterval = 0
    36. End Sub
    37.  
    38. Public Property Let Interval(ByVal vNewValue As Variant)
    39.     m_CountDownInterval = vNewValue
    40.     If m_CountDownInterval < 0 Then
    41.         m_CountDownInterval = 0
    42.     End If
    43. End Property
    44.  
    45. Public Property Get Interval() As Variant
    46.     Interval = m_CountDownInterval
    47. End Property
    48.  
    49. Private Sub IncrementCountDown(lngIntervals As Long)
    50.     '
    51.     If Not m_blnRunning Then
    52.         m_Timer.StartTimer m_CountDownInterval
    53.         m_blnRunning = True
    54.         RaiseEvent Started
    55.     End If
    56.     '
    57.     m_ActiveIntervals = m_ActiveIntervals + lngIntervals
    58.     '
    59. End Sub
    60.  
    61. Public Sub Increment()
    62.     IncrementCountDown 1
    63. End Sub
    64.  
    65. Public Sub MultiIncrement(lngIntervals As Long)
    66.     IncrementCountDown lngIntervals
    67. End Sub
    68.  
    69. Private Sub m_Timer_Refresh()
    70.     '
    71.     If m_blnRunning = True Then
    72.         m_ActiveIntervals = m_ActiveIntervals - 1
    73.         RaiseEvent Refresh
    74.     End If
    75.     '
    76.     If m_ActiveIntervals = 0 Then
    77.         '
    78.         m_Timer.StopTimer
    79.         m_blnRunning = False
    80.         RaiseEvent Finsihed
    81.     End If
    82.     '
    83.     '
    84. End Sub
    85.  
    86. Public Property Get ActiveIntervals() As Variant
    87.     ActiveIntervals = m_ActiveIntervals
    88. End Property
    89.  
    90. Public Property Get Running() As Boolean
    91.     Running = m_blnRunning
    92. End Property
    Last edited by Dave Sell; Mar 16th, 2010 at 04:33 PM.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  2. #2
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    Hi,

    Is there a way to copy and paste this code without the line numbers ?

    Cheers
    Ian

  3. #3

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    Give me a few mins and I will upload the modules.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  4. #4
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    I've just noticed that if I click the "Quote" button it displays all the text in the box without the line numbers - I suppose it would be easy enough to pull the text out that way - on the other hand, isn't there an 'official' way to copy code samples from the forum ?

    By the way, the first line is going to give me an error isn't it ?

    Private WithEvents m_COMPort As cls_COMPort

    Only allowed in an Object Module

    I'm doing this in a standard exe project - should I be doing it in an activex exe project ?

  5. #5

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    Standard EXE project is perfect. I always use a Main Form to host all the main WithEvents Objects. The Quote trick is the official way to do it LOLz...
    Last edited by Dave Sell; Mar 19th, 2010 at 08:48 AM.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  6. #6

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    OK I'm uploading the project files. Note I altered CountDownTimer.cls to use Strings instead of Variants, which are not compatible with .NET
    Attached Files Attached Files
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  7. #7
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    Hi Dave - I just downloaded that and took a quick look at the code.

    I haven't actually tested it yet with a slow port but would you just clarify for me - what you're saying is that (when I click the "Open Async" button) if the API CreateFile function hangs (ie does not return for any length of time) then the application will still remain responsive and can periodically check to see if the port opened yet.

    So, in theory, one could use that sample code to do practically 'anything' on an async basis.

    You said you wrote much of that code some time ago - was that its purpose ? to do api tasks asynchronously ? Where is that code, I couldn't see it in the codebank.

    Thanks
    Ian

  8. #8

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by IanS View Post
    Hi Dave - I just downloaded that and took a quick look at the code.

    I haven't actually tested it yet with a slow port but would you just clarify for me - what you're saying is that (when I click the "Open Async" button) if the API CreateFile function hangs (ie does not return for any length of time) then the application will still remain responsive and can periodically check to see if the port opened yet.
    Short answer is yes, but I would not "check periodically". I would set up my own timer on the form that alerts me that n seconds have gone by and I should try again later, etc. However I don't think there is much you can do besides wait for the API call to return. Like I don't think you can cancel that call or anything, you just gotta let it run its course.

    Quote Originally Posted by IanS View Post
    So, in theory, one could use that sample code to do practically 'anything' on an async basis.
    Yes!

    Quote Originally Posted by IanS View Post
    You said you wrote much of that code some time ago - was that its purpose ? to do api tasks asynchronously ? Where is that code, I couldn't see it in the codebank.
    I made 2 Classes many years ago that used bits of that code; One was the CountDownTimer to be used as a non-graphical Windows Timer, and the other is clsPerformanceCounter, which can be used to measure the time it takes code to execute, and is accurate down to 300 nanoseconds.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  9. #9
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    Originally Posted by IanS
    So, in theory, one could use that sample code to do practically 'anything' on an async basis.

    Quote Originally Posted by Dave Sell View Post
    Yes!
    This sounds interesting. I don't have a slow port ready to test so I thought of some 'other' api call I could test this with. Sleep() should do it. So I added the declaration for the API Sleep() function.

    So, calling Sleep(10000) instead of CreateFile would make the application hang for 10 seconds - but, according to you, the main form should remain responsive while we're waiting for the API call to return.

    But it doesn't, the call makes everything hang for 10 seconds.

    Maybe Sleep isn't a good one to test this with - can you think of some other slow api call we could use to test this ?
    Last edited by IanS; Mar 20th, 2010 at 12:15 PM.

  10. #10

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    Post code and I will try it sometime next week.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  11. #11
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    I've just added the Sleep function to your code.

    Code:
    Option Explicit
    '
    ' VB Module: mod_ComTest.bas
    '
    Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
        (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
        ByVal dwShareMode As Long, lpSecurityAttributes As Any, _
        ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
        ByVal hTemplateFile As Long) As Long
    '
    '// This is the declaration to close the COM port
    Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    
    Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    and commented out the call to CreateFile and called Sleep() instead because we know that, in this case, the api call with take 10 seconds to return

    Code:
    Public Function OpenPort() As Boolean
        
        ' Instead of CreateFile, lets call Sleep(10000)
        ' Obviously this isn't going to open a port but we can be sure that this api call will take 10 seconds to return
        
         Sleep (10000)
        
        '
        '
        ' m_lngFileHandle = CreateFile("\\.\COM1", GENERIC_READ Or GENERIC_WRITE, 0, ByVal 0&, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0)
        '
        '    If m_lngFileHandle > 0 Then
        '        OpenPort = True
        '    End If
        
    End Function
    Last edited by IanS; Mar 20th, 2010 at 12:33 PM.

  12. #12

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    OpenPort() is not an Asynchronous routine.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  13. #13
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by Dave Sell View Post
    OpenPort() is not an Asynchronous routine.
    If I click the OpenAsync button on your sample form that eventually calls OpenPort - I assumed you did that because that's the only place anywhere in your code that CreateFile() appears.

  14. #14

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    Oh ya, sorry. I don't have VB6 installed anymore, so next week I will install it and look into this.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  15. #15
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    This function calls OpenPort()

    Code:
    Private Sub m_OpenTimer_Finsihed()
        '
        Dim blnReturn As Boolean
        '
        blnReturn = OpenPort
        RaiseEvent PortOpenDone(blnReturn)
        '
    End Sub

  16. #16

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by IanS View Post
    This function calls OpenPort()

    Code:
    Private Sub m_OpenTimer_Finsihed()
        '
        Dim blnReturn As Boolean
        '
        blnReturn = OpenPort
        RaiseEvent PortOpenDone(blnReturn)
        '
    End Sub
    OK but the main form should not be "hung up" not matter how long this takes.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  17. #17
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    With the above changes (using Sleep instead of CreateFile) the main form hangs for 10 seconds when I click the OpenAsync button

  18. #18

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    If that is really true then I will try it using an out-of-process EXE object instead of the in-process way we are doing it now.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  19. #19

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by IanS View Post
    With the above changes (using Sleep instead of CreateFile) the main form hangs for 10 seconds when I click the OpenAsync button
    According to MSDN: here, Sleep() kills the entire thread, parental ownership not excluded.

    Ergo, what you are witnessing is by design and should not in any way correlate to the CreateFile API. Sleep is intended to kill the entire thread.

    I suggest you ignore this test, even though I thought it was a pretty good shot at simulating the hung-up nature of the CreateFile() API call.

    I believe you cannot have a true test of the true behavior until you run it against a problematic COM port, as I originally suggested.

    I will try to simulate this using CreateFile against a broken mapped network drive and see what happens.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  20. #20
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by Dave Sell View Post
    According to MSDN: here, Sleep() kills the entire thread, parental ownership not excluded.

    Ergo, what you are witnessing is by design and should not in any way correlate to the CreateFile API. Sleep is intended to kill the entire thread.

    I suggest you ignore this test, even though I thought it was a pretty good shot at simulating the hung-up nature of the CreateFile() API call.

    I believe you cannot have a true test of the true behavior until you run it against a problematic COM port, as I originally suggested.

    I will try to simulate this using CreateFile against a broken mapped network drive and see what happens.
    Mentioning the word 'Thread' - I think you hit the nail on the head.

    The ability to run a 'slow-to-return' CreateFile function AND remain responsive within the application while you're waiting would, in my mind, require two threads.

    If we were doing this in C we'd call the CreateThread API to do the async task. Actually, in VB5 you could also call CreateThread and pass it AddressOf a function in a module to do the async task - basically running two threads.

    VB6 is more thread-safe so that crashes if you try (although there are ways around it but it requires a bit more code but still possible - I may look at that route)

    Without multithreading I really can't see how we can be running code in the API CreateFile function AND running code in the VB form at the same time with just one thread.

    I really do appreciate your input on this - but please don't spend too much time on it because I kinda feel we're going down the wrong route.

  21. #21
    PowerPoster CDRIVE's Avatar
    Join Date
    Jul 2007
    Posts
    2,620

    Re: Asynchronous Open and Close of COM port

    Using Sleep for more than a few mS is an awful idea. Take a look at the WaitMessage API used in conjunction with a Timer or use this Pause sub, which is a modified of version of what's found in your library. This sub will not freeze your app. You can click buttons etc. while Pause is active.

    Code:
    Private Sub Pause(ByVal Delay As Single)
       Delay = Timer + Delay
       If Delay > 86400 Then 'more than number of seconds in a day
          Delay = Delay - 86400
          Do
              DoEvents ' to process events.
              Sleep 1 ' to not eat cpu
          Loop Until Timer < 1
       End If
       Do
           DoEvents ' to process events.
           Sleep 1 ' to not eat cpu
       Loop While Delay > Timer
    End Sub
    
    Private Sub Form_Load()
       Pause 10                    ' pause for 10 seconds
       MsgBox "Time Out"
    End Sub
    <--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
    If topic has been resolved, please pull down the Thread Tools & mark it Resolved.


    Is VB consuming your life, and is that a bad thing??

  22. #22

    Thread Starter
    PowerPoster Dave Sell's Avatar
    Join Date
    Mar 2004
    Location
    /dev/null
    Posts
    2,961

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by CDRIVE View Post
    Using Sleep for more than a few mS is an awful idea. Take a look at the WaitMessage API used in conjunction with a Timer or use this Pause sub, which is a modified of version of what's found in your library. This sub will not freeze your app. You can click buttons etc. while Pause is active.
    Ya actually IanS was intentionally freezing the app to run a test, or prove a point. I am not convinced the test is a valid comparison to the behavior of a hung-up API call to CreateFile(). I have not tried it yet.
    Nobody knows what software they want until after you've delivered what they originally asked for.

    Don't solve problems which don't exist.

    "If I had eight hours to cut down a tree, I'd spend six hours sharpening my axe." --- Abraham Lincoln (1809-1865)

    2 idiots don't make a genius.

  23. #23
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by CDRIVE View Post
    Using Sleep for more than a few mS is an awful idea.....
    LOL yeah we know - you'd need to read the whole thread from the start to see what we're talking about.

    Dave is trying to put some code together that would allow a VB6 app to call a 'blocking function' while still remaining responsive. By 'Blocking Function' I mean calling some API function that might take a very (very) long time to return without blocking the calling application. To test Dave's code I thought we could use the Sleep function (that will block for as long as we tell it to)

    I've come to the conclusion it can only be done by actually creating another thread to make the api call - Dave is doing it in just one thread.

    Please join in though - all suggestions welcome

  24. #24
    PowerPoster CDRIVE's Avatar
    Join Date
    Jul 2007
    Posts
    2,620

    Re: Asynchronous Open and Close of COM port

    Well, we know that VB6 can't multi-thread but I did mention the WaitMessage API in that post. Admittedly, I'm not sure if it's applicable here.

    Quote: From the KPD API Guide:

    "The WaitMessage function yields control to other threads when a thread has no other messages in its message queue. The WaitMessage function suspends the thread and does not return until a new message is placed in the thread’s message queue".
    <--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
    If topic has been resolved, please pull down the Thread Tools & mark it Resolved.


    Is VB consuming your life, and is that a bad thing??

  25. #25
    Fanatic Member
    Join Date
    Mar 2009
    Posts
    739

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by CDRIVE View Post
    Well, we know that VB6 can't multi-thread
    Actually it can - You can call the CreateThread API function passing it AddressOf a sub or function in a module.

    That worked quite well under VB5 but crashes when you try it with VB6 - interesting thing is it's the new thread that crashes while the calling thread remains responsive That kinda feels strange seeing the error messages pop open but still have full control of your application - LOL

    Anyway, it is still possible with vb6 to call the CreateThread api function. It just needs a bit more code to set it up before calling it.

  26. #26
    PowerPoster CDRIVE's Avatar
    Join Date
    Jul 2007
    Posts
    2,620

    Re: Asynchronous Open and Close of COM port

    Quote Originally Posted by IanS View Post
    Actually it can - You can call the CreateThread API function passing it AddressOf a sub or function in a module.

    That worked quite well under VB5 but crashes when you try it with VB6
    That's unfortunate, because if it worked under VB6 it could be used to generate DTFM codes and a host of other applications.
    <--- Did someone help you? Please rate their post. The little green squares make us feel really smart!
    If topic has been resolved, please pull down the Thread Tools & mark it Resolved.


    Is VB consuming your life, and is that a bad thing??

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width