thank you , successful!!
Printable View
thank you , successful!!
hi Krool:
Code:For i = 1 To 10
Set mthread(i) = New Thread
If InIDE() = True Then
'MsgBox "In the IDE the threads are synchronous to the main thread." & vbLf & "DebugMode is set to True. (determined by the InIDE() function)", vbInformation + vbOKOnly
mthread(i).DebugMode = True '
End If
mthread(i).Create Me, "TD" + CStr(i)
Next
if i used 10 threads,download 100 (10×10) pics .when i make exe and run.Code:Private Sub IThread_BackgroundProcedure(ByVal Key As String, _
ByVal StatusCallback As VBMThread11.IThreadStatusCallback, _
ByVal Data As VBMThread11.ThreadData)
Dim i As Integer, IsDebugMode As Boolean
IsDebugMode = Data.DebugMode
For i = 1 To 10
StatusCallback.Raise (Mid(Key, 3) - 1) * 10 + i
sleep 100
If IsDebugMode = True Then DoEvents
Next
End Sub
The program is stuck and can not be moved using the mouse untile the 10 threads complete.
if i change sleep 100 to doevents. can not useful. can have good ideas?
@ xxdoc123, you need to place your download code into BackgroundProcedure and not in StatusCallback.
All code should be in BackgroundProcedure. The StatusCallback is only a bridge to interact with the VB main thread, e.g. updating a ProgressBar etc.
@ xxdoc123, the problem lies in the fact that you use 'App.Path' within the BackgroundProcedure. You should store the save the path string within Form_Load and store it in a string which you then use within your GetData function that is called within BackgroundProcedure.
i know,can not used cls。
I have got it to work.
What you Need to do is as following:
form-Level declarations:
During Form_Load:Code:Private AppPath As String, http As clshttp
Implements IThread '
New GetData function:Code:Private Sub Form_Load()
AppPath = App.Path
Set http = New clshttp
Code:Public Function GetData(temp As Integer) As Boolean '
' Sleep 200
TestStr = "Test" + CStr(temp)
'Dim http As clshttp
'Set http = New clshttp
If http.Download("http://www.vbforums.com/images/misc/logo.gif", AppPath & "\test\" & TestStr & ".gif") = True Then
GetData = True
End If
'Set http = Nothing
End Function
yes.your are right.now work ok.thanks
@ xxdoc123, one more thing.
You use the .Cancel method somewhere, in order to be meaningful you need to add the following within in For..Loop in the BackgroundProcedure.
Code:If Data.CancellationPending = True Then
Data.Canceled = True
Exit For
End If
This is just a question put in the room. Out of curiosity!
The VBMThread11.DLL will just work fine in 32-bit VBA office. Whether .DebugMode is True or False.
However, by certain registry hacks (https://techtalk.gfi.com/32bit-objec...t-environment/) it is possible to reference a 32-bit COM dll in 64-bit environment. (e.g. 64-bit VBA office)
So in 64-bit VBA office the referencing works. But the threading does only work when using .DebugMode = True. (single-threaded)
When changing .DebugMode = False (true multi-threading) nothing happens. I mean really nothing. Not even a crash happens. The only thing happens is that the active UserForm becomes inactive, but the BackgroundProcedure in IThread never got called.
I don't know if anybody can give me an answer to this. Just wanted to put this out, as said, out of curiosity..
I guess I have the answer to my question.
It seems the registry tweak just allows to interoperability between 64bit and 32bit in a "interface wise" mean.
So 32bit can still not be "hosted" in 64bit environment. And by hosted is kind of an ActiveX control or in this sense a "call" from a 32bit thread to a 64bit environment.
The reason why it works with .DebugMode = True is because as the main 64bit thread will run its own call.
So the benefits of that DllSurrogate registry tweaks are limited..
These registry "hacks" seem to register the x86 component as a COM+ application which as a consequence makes you library an out-of-process component for the x64 client.
cheers,
</wqw>
Is any help from Microsoft Website?
https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
Included LinkSwitch /OPT:NOWIN98 on the VBCompiler which reduced the file size of the DLL from 48KB to 36KB
Hi for all
I need to use multithreading. I did a test using the VBMThread11 DLL.
I downloaded the xxdoc123 test program.
I do not understand why I do not receive an indication of the end of the thread execution with the msgbox inserted for this.:confused:
Furthermore, the sequence of thread execution does not seem to be as expected.
Thanks
You have a logic error, try instead of:
the following:Code:Private Sub IThread_Complete(ByVal Key As String, ByVal Data As VBMThread11.ThreadData)
If Data.Canceled = False Then
Debug.Print Mid(Key, 3) & "complete"
Debug.Print Mid(Key, 3) & "mThreadid=" & mThread((Mid(Key, 3))).hThread
Else
MsgBox Mid(Key, 3) & "mThread have end", vbInformation + vbOKOnly
End If
End Sub
Code:Private Sub IThread_Complete(ByVal Key As String, ByVal Data As VBMThread11.ThreadData)
If Data.Canceled = False Then
If Data.DebugMode = True Then
Debug.Print Mid(Key, 3) & "complete"
Debug.Print Mid(Key, 3) & "mThreadid=" & mThread((Mid(Key, 3))).hThread
Else
MsgBox Mid(Key, 3) & "mThread have end", vbInformation + vbOKOnly
End If
End If
End Sub
The test was successful, but unfortunately can not be used for database queries: in the query did not complete the progress bar or not move.
If you use directly on SQL server it might work.
If you use on jet access db then not as async processing is not possible. The task are done in a queue one by one so even multithreading does not help.
Edit: And for example when using ADO you can then execute a query in StatusCallback via the main project ADODB conn with the dbAsync option. But again, does not work on access db.
I'm using this. May I have this, please?Code:Public Function ExecuteSQL(ByVal SqlStr As String, Optional ErrMsg As String) As ADODB.Recordset
0 On Error GoTo ExectueSql_Error
Dim Mycon As ADODB.Connection
Dim rst As ADODB.Recordset
Set Mycon = New ADODB.Connection
Mycon.ConnectionString = ConnString
Mycon.ConnectionTimeout = Val(lTmr) + 1
Mycon.Open
Dim stokens() As String
On Error GoTo ExectueSql_Error
stokens = Split(SqlStr)
If InStr("INSERT,DELETE,UPDATE", UCase(stokens(0))) Then
Mycon.Execute SqlStr
Else
Set rst = New ADODB.Recordset
rst.CursorLocation = adUseClient
'rst.Properties("Initial Fetch Size") = 50
rst.Open Trim(SqlStr), Mycon, adOpenKeyset, adLockOptimistic ',adCmdText
Set ExecuteSQL = rst
End If
ExectueSql_Exit:
Set rst = Nothing
Set Mycon = Nothing
Exit Function
ExectueSql_Error:
If err.Number = -2147467259 Then '解决 Named Pipes 错误
SaveRegistryKey HKEY_LOCAL_MACHINE, "SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo", strServerName, "DBMSSOCN," & strServerName
ErrMsg = "连接数据库服务器 " & " 错误:" & vbCrLf & vbCrLf & err.Description
Else
ErrMsg = err.Description
End If
'WriteErrLog ErrMsg
Resume ExectueSql_Exit
End Function
Yesterday's test was ADO data control, which has been tested.
With your suggestion the program works.
you excuse my banality, but I did not understand some things.
1)
Because we need the timer to check if all the threads are finished.
The IThread_Complete event could not be used for this.
2)
The IThread_BackgroundProcedure is a procedure is not an event? Quite right?
3)
Is IThread_Complete an event?
It is not generated when the thread ends as the name would seem to say.
4) The IThread_StatusCallback event is generated by the program. But is it always like this?
The thread that is executed does not generate it?
Thank
IThread is an interface definition and not event driven. It's called by interface methods.
Interface method when a thread's background procedure is called.
Interface method when a thread's background procedure has been completed or canceled.Code:Public Sub BackgroundProcedure(ByVal Key As String, ByVal StatusCallback As IThreadStatusCallback, ByVal Data As ThreadData)
StatusCallback.Raise 1&, "Test" ' StatusCallback method called.
End Sub
The Thread is already terminated (hThread = 0) when this method is called.
Interface method when a thread requests an synchronous status callback. The background thread will be suspended, the method request is marshaled to the main thread.Code:Public Sub Complete(ByVal Key As String, ByVal Data As ThreadData)
End Sub
Code:Public Sub StatusCallback(ByVal Key As String, ByRef Argument1 As Variant, ByRef Argument2 As Variant)
End Sub
Hi Krool.
Thanks.
Now it is a bit more clear.
You have to excuse me, but I now approach this advanced programming.
I still have a small question.
Why is this thread called "(Multithreading generic)"?
Are there any other types of multithread?
The official VB6 multithreading is a ActiveX EXE. Like a COM DLL it must be registered.
However, "your code" must be placed inside that ActiveX EXE. So for each purpose or task you may need to change that ActiveX EXE or create another one.
This generic DLL allows to place "your code" inside your "own app". So for whatever task or purpose you can change "your app".
This is meant by "generic". The DLL remains always unchanged.
but if there are the activeX:confused: because one needs to use other paths?
OK. Thanks
May have what?
The best is you create the ADODB.Connection and ADODB.Recordset within the IThread_BackgroundProcedure from scratch (Early-bound works from main thread references) and then just execute or do your queries form there and communicate your results via StatusCallback. No dbAsyncExecute needed.
However, as said when using access mdb files it's not working since file locking. On SQL server it should work just well.
JFYI, when sample project VBMThread11Demo.zip is compiled to P-Code all samples seem to freeze which is very weird.
The multi-threader is left natively compiled DLL, only the IThread interface implementation is P-Code compiled and still the runtime doesn't like this scenario.
cheers,
</wqw>
Dear Krool,
First of all, I wish to inform that this is the first time I have found the need to go in for MultiThreading. So, while searching in the net, I landed first on Olaf's solution - at https://www.vbforums.com/showthread....-(simple-Demo) - which led to https://www.vbforums.com/showthread....rot-Rendering) - which provides a DLL route also to achieve MultiThreading. I have not explored these solutions yet.
Point A)
Coming to your solution, kindly educate/clarify on the following. I am asking these for clear understanding on the fundamental things, during development and deployment.
--
1. Registering VBMThread11.DLL alone is enough as far as I keep working on my "Development" machine. Right?
2. My source project needs to include the Side-by-side resource ONLY in the case of the ""End user" machine. Right? And this inclusion is required so that registration of the DLL can be avoided in user-end. Right? In other words, if DLL registration is done in user-end also, then inclusion of your side-by-side resource ("VBMThread11SideBySide.res") in my project is not required. Right?
3. Even in my "Development" system, if I include your side-by-side resource ("VBMThread11SideBySide.res") in my project, then registering of the DLL is not necessary in my "Development" system too. Right?
--
Though I will be eventually including your side-by-side resource in my project so that registration is avoided at user-end, still for my understanding purpose, I request you to educate me on the above 3 questions, so that I get a clear understanding of the fundamental matters.
Point B)
Coming to the task of including your side-by-side resource in my source project, how exactly should I do that? I am asking this because I already have an existing .res file in my project and VB6 allows to add only one resource file at any time.
Further, when I open my project's existing .res file in Notepad, I find that its top few lines are almost exactly the same as the contents## I find in the 'Resources.res' file in the "..\..\VBMThread11Demo\Resources" directory of yours. Thereafter, the details in my .res file pertain to the other files (quite many) I have added to it later on, via the VB6 IDE.
The top few lines of contents##, as far as I have understood over the years, pertain to the 'Visual Styles' aspect. So, what I need to add now to my project are only the contents of your "VBMThread11SideBySide.res" file. Right? But, how do I add the contents of your "VBMThread11SideBySide.res" file into my already existing .res file? What is the correct procedure so that the added contents do what they are supposed to do. Kindly please let me know.
I used "Add Custom Resource" in the 'VB Resource editor' to add "VBMThread11SideBySide.res" to my .res file. After that, when my .res file is viewed in Notepad, I see that the contents of "VBMThread11SideBySide.res" gets added at the very end of my .res file. Is this correct? Will this be enough for safe deployment of my app at user-end? If not, kindly let me know the correct procedure.
I also read some years back that the .res file size should be a multiple of 4096 or something like ,that. I don't know in relation to what I read that info. Should that be the case for my .res file too after adding the contents of "VBMThread11SideBySide.res" to it. If so, how to ensure that correct size for my .res? Kindly educate.
Point C)
Well, apart from the above procedure which I request you to let me know, if I use Olaf's "DirectCom.DLL' method, then that will also automatically register your "VBMThread11.DLL" in end-user machine. Right? If so, no need to add the contents of "VBMThread11SideBySide.res" to my .res file. Right?
I take this opportunity to once again thank you for all your fabulous free contributions so far. God Bless you! God Bless all!
Kind Regards.
(##)
--
ÿÿ ÿÿ ˜ ÿÿ ÿÿ 0 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" language="*" processorArchitecture="*" publicKeyToken="6595b64144ccf1df"/>
</dependentAssembly>
</dependency>
</assembly>
--
Edit 1:
- While using "Add Custom Resource", I did move the added content to "#24" and gave '2' for ID since the earlier manifest contents (for Visual Styles) I have under "#24" has the ID '1' already.
- While waiting to see the perfectly right procedure from you, I did try ResourceHacker; added the contents of "VBMThread11SideBySide.res" below the already existing contents of ID 1 under "#24"; saved into a new .res file (say aaa.res); deleted the existing .res in my project; tried to add aaa.res to my project but it did not get added. Probably the DWord alignment was not present.
- Will try the code given by LaVolpe (at https://www.vbforums.com/showthread....=1#post5485439) soon.
Edit 2:
Tried the code given by LaVolpe. Seems to do the same thing as I did manually using "Add Custom Resource" except that the combined .res file got by using LaVolpe's code was few bytes lesser than the updated .res file I got after I manually modified it using "Add Custom Resource".