I believe this may have already been answered here:
How to simulate held down keys with VB.NET or C#?
They do mentioned that DoEvents may not be the best thing to do in a loop like so, here is an alternative approach: https://www.experts-exchange.com/questions/22634280/Holding-a-key-down-my-code-not-working-VB-NET.html
and in case the link dies:
If you want to simulate a "real" keyboard sleep, I would then go with system settings for keyboard delay/speed. THis can be done with SystemParametersInfo API
Const SPI_GETKEYBOARDDELAY = 22
Const SPI_GETKEYBOARDSPEED = 10
Private Declare Function SystemParametersInfo Lib "user32" Alias _
"SystemParametersInfoA" (ByVal uAction As Integer, ByVal uParam As Integer, _
ByRef lpvParam As Integer, ByVal fuWinIni As Integer) As Integer
Private Sub HoldKeyDown(ByVal key As Byte, ByVal durationInSeconds As Integer)
Dim targetTime As DateTime = DateTime.Now().AddSeconds(durationInSeconds)
Dim kb_delay As Integer
Dim kb_speed As Integer
SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, kb_delay, 0)
SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, kb_speed, 0)
While targetTime.Subtract(DateTime.Now()).TotalSeconds > 0
keybd_event(key, MapVirtualKey(key, 0), 0, 0) ' Up key pressed
keybd_event(key, MapVirtualKey(key, 0), 2, 0) ' Up key released
System.Threading.Thread.Sleep(kb_delay + kb_speed)
End While
End Sub
Not sure if this'll work, seems it's just pressing the key a bunch - I've not had a chance to test this