-
Re: VB Multithread Library (Generic Multithreader)
You could even set DebugMode automatically ( GetModuleHandle("vba6"))
I don't think TerminateThread would be very nice to the COM STA, on your background thread :/
but we're in uncharted territory :)
and since you're adding everyone else's suggestions - maybe you can architect in a threadpool,
where you have some control over the STA's message loop. then you can use messaging to initiate thread tasks, and reliably marshal interfaces both ways.
this would also reduce the overhead in initializing COM on each thread.
I like this component, it's already very usable, even without any changes.
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
DEXWERX
You could even set DebugMode automatically ( GetModuleHandle("vba6"))
I don't think TerminateThread would be very nice to the COM STA, on your background thread :/
but we're in uncharted territory :)
and since you're adding everyone else's suggestions - maybe you can architect in a threadpool,
where you have some control over the STA's message loop. then you can use messaging to initiate thread tasks, and reliably marshal interfaces both ways.
this would also reduce the overhead in initializing COM on each thread.
I like this component, it's already very usable, even without any changes.
I don't want fix DebugMode when in IDE. Because in my testings it does "work" in the IDE, but there is a risk of a crash. The only thing what would make sense is to dissallow DebugMode when not in IDE. But anyhow I'm not a fan of such restriction.
About your message loop idea. That does not make sense actually. The thread sends a request to the client and there you can make whatever you like until that returns. So in the BackgroundProcedure (currently known as AsyncProcedure) you can do your own loop to whatever condition.
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
LaVolpe
Maybe a terminate event can be raised after the thread is killed. But additionally, passing a value to that event that is set inside the SyncCallback event. Maybe your ThreadCancelBoolean idea can have another property (variant, user defined)? And that value is passed to the terminate event? As a workaround, I was considering a timer event or PostMessage type event (asynchronous). However, a terminate event with optional value would be ideal I think.
I was able to fire a IThread_Complete when the thread is terminated, trough a Timer in the Ax-DLL that checks for:
Code:
WaitForSingleObject(PropThreadHandle, 0) = WAIT_OBJECT_0
However, there is a small detail to check.
When that IThread_Complete is fired, should the PropThreadHandle already be closed? (via CloseHandle)
If yes, then it would be possible to create the "same thread" again in the Complete "event". (like a recurrence)
EDIT: I will allow recurrence, as depending on the result it perhaps is necessary to "re-run" the background procedure.
-
Re: VB Multithread Library (Generic Multithreader)
Major updated released to version 1.1.
The version 1.1 needs a new manifest in order to run registration-free. The manifest can be found here.
The demo project is also a little bit enhanced to reflect some improvements and the increased flexibility.
All changes are described in the list of revisions. However, I will explain them again in more detail now.
The Thread class is not event driven anymore, instead it is interface driven.
This means an IThread interface will receive all the thread related "events".
Thus in the Create method there is an Owner parameter included, which is mandatory.
In this you specify the receiver object, normally a Form. But it can also be in another class. (as long as IThread is implemented)
The optional Key parameter in the Create method will help you for sure when you want or need to create more than one thread on the same receiver.
The AsyncProcedure event has been renamed to BackgroundProcedure and SyncCallback got renamed to StatusCallback.
The new included Complete event will fire after the BackgroundProcedure is returned and the thread handle is finally closed.
Included the new ThreadData class object that will be passed in BackgroundProcedure and Complete event.
That Data param has a Tag, Canceled and CancellationPending and DebugMode property. (DebugMode described later on)
The Tag property can be used to store some final data to be processed in the Complete event. The CancellationPending is read-only and returns True when from "outside" a cancel request was sent via the new included Cancel method. This is the preferred method to cancel a thread, instead of terminating it. However, how fast and efficient the cancel request is is totally dependent on the developer and the code in the BackgroundProcedure.
When CancellationPending is True and you want to exit the BackgroundProcedure then you may also set the Canceled property to True.
This way in the Complete event you can evaluate if the task was completed or canceled and if necessary re-start directly.
Included an optional Wait parameter in the Terminate method, so the method returns only until the thread is finally terminated. (not recommended, use new cancel request approach)
Also included the DebugMode property. If set to True the background thread runs synchronous to the main thread. This does allow to safely set breakpoints and perform debugging in the IDE.
The Data object (ThreadData) will also hold a copy of the DebugMode property, so in the BackgroundProcedure you can check for Data.DebugMode and do so some DoEvents in that case to keep the UI responsive while debugging in the IDE.
-
Re: VB Multithread Library (Generic Multithreader)
The only "issue" left is when setting the Thread class to Nothing (Set) while the thread is running the Class_Terminate will not be fired as a shadow reference is being held by the background thread.
So before doing Set = Nothing, do a .Terminate before.
However that should be only done in an emergency case.
-
Re: VB Multithread Library (Generic Multithreader)
Krool, the description of the changes sounds really nice. Should give coders far more flexibility.
If you consider this, I think the only major enhancement remaining would be to create this in a standard DLL vs. an ActiveX DLL. This is something I've been contemplating but not gotten serious about yet. The idea could allow ocx's, for example, to drop the standard DLL in its install folder and create threads without worrying about DLL registration. I'm still a bit green around the edges when it comes to multi-threading. I don't know if your SxS manifest would apply to a compiled ocx or not? Still much to learn myself.
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
LaVolpe
I don't know if your SxS manifest would apply to a compiled ocx or not? Still much to learn myself.
It should be possible to include the manifest for the dll in the ocx.
And the app who finally use the ocx can implement a manifest for the ocx.
Did not try.. maybe the final app needs to manifest both ocx and dll. (?) Or maybe only when the dll got exposed in the ocx, if used privately not needed. (?)
This would require testings to give a sure answer.
-
Re: VB Multithread Library (Generic Multithreader)
The manifest resource ID must be 2 instead of 1 when including the dll manifest in a ocx. However, testings needed.
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
maybe the final app needs to manifest both ocx and dll
From what I've read, any app that tries to use an ocx SxS without registration, needs to include the ocx and its dependencies (i.e., the dll). There may be examples on this site; I'll research when I find time.
Quote:
Originally Posted by
Krool
The manifest resource ID must be 2 instead of 1 when including the dll manifest in a ocx. However, testings needed.
Good point and worth highlighting
-
Re: VB Multithread Library (Generic Multithreader)
anecdotal evidence but this new version (with DebugMode = False)
seems more stable in the IDE than version 1.
App.ThreadID can be called without issue from the IThread_BackgroundProcedure()
edit: this seems ready for primetime.
FYI the .NET equivalent is the BackgroundWorker class, which might be closer to VBMThread10, due to using (less efficient) events.
I really don't have anything to critique. (You could flesh out the entire .NET threading system, but this is awesome for 99% of tasks VB is used for)
How's your flexgrid coming? :)
:thumb:
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
DEXWERX
Why would you need this in an ActiveX EXE, considering an ActiveX EXE can use VB6's standard multithreading methods?
(setting the Threading Model)
Hi,
Sorry i meant to merge it with a standard exe to avoid the Dll dependencies.
-
1 Attachment(s)
Re: VB Multithread Library (Generic Multithreader)
Hi ~ Krool
I find a program
please help me, thank you.
VB6 Code Sample [Attachment Removed by Moderator for containing an executable]
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
quickbbbb
I find a program
please help me, thank you.
Please explain in more detail and provide real source code, no finished .exe (!) file.
-
Re: VB Multithread Library (Generic Multithreader)
===================
source code
[Attachment Removed by Moderator for containing an executable]
===================
Private Sub IThread_BackgroundProcedure(ByVal Key As String, ByVal StatusCallback As VBMThread11.IThreadStatusCallback, ByVal Data As VBMThread11.ThreadData)
For w = 1 To 10^9 ' a large loop
Text1 = Val(Text1) + 1 ' TextBox control add 1
If Check_Auto_Pause.Value Then
If w Mod 1000 = 0 Then
Call cmd_Start_Pause_Click
' about detail
'(1) when w mod 1000 =0 , program will call cmd_Start_Pause_Click , and IThread will be pause
'(2) Then I use mouse click botton cmd_Start_Pause, but IThread can not resume to run
End If
End If
Next
End Sub
Private Sub cmd_Start_Pause_Click()
' when click repeat , will pause -> start -> pause -> start ........
On Error Resume Next
Thread.Suspended = Not Thread.Suspended
Text3 = "Suspended_Ststus= " & Thread.Suspended
End Sub
-
Re: VB Multithread Library (Generic Multithreader)
detail part 2
check_Auto_Pause is not selected and use mouse click botton start/pause ->
textbox will appear 1,2,3,4,5.....1000 ->
use mouse click botton start/pause again -> textbox add 1 will Suspended thread ->
use mouse click botton start/pause again -> textbox add 1 will resume thread run -> .....
It work very good
detail part 3
check_Auto_Pause is selected and use mouse click botton start/pause ->
textbox will appear 1,2,3,4,5.....1000 ->
when textbox.text = 1000 , thread will be suspended auto by program ->
now use mouse click botton start/pause again ->
but thread can not resume to run
-
Re: VB Multithread Library (Generic Multithreader)
It is not recommended to access project objects within BackgroundProcedure, unless there are created in it. Instead put them to StatusCallback. (especially the "Call cmd_Start_Pause_Click")
-
1 Attachment(s)
Re: VB Multithread Library (Generic Multithreader)
ok , thank you.
I forget remove exe file
now there are only text code
Source code
Attachment 148297
-
1 Attachment(s)
Re: VB Multithread Library (Generic Multithreader)
' crash when call class sub qq
Private Sub IThread_BackgroundProcedure(ByVal Key As String, ByVal StatusCallback As VBMThread11.IThreadStatusCallback, ByVal Data As VBMThread11.ThreadData)
Text1 = Val(Text1) + 1
c0.qq 'call class sub qq
End Sub
===============
Source Code
Attachment 148301
-
1 Attachment(s)
Re: VB Multithread Library (Generic Multithreader)
very sorry
source code lost some file
reupload
Attachment 148309
-
Re: VB Multithread Library (Generic Multithreader)
Again: use StatusCallback when you want to access objects created NOT within the BackgroundProcedure.
-
Re: VB Multithread Library (Generic Multithreader)
-
1 Attachment(s)
Re: VB Multithread Library (Generic Multithreader)
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
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
if i used 10 threads,download 100 (10×10) pics .when i make exe and run.
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?
-
Re: VB Multithread Library (Generic Multithreader)
@ 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.
-
1 Attachment(s)
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
Krool
@ 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.
now i change the code what you say. but can used in ide,not run if make to exe. can you have a litter time to look my code?
thanks.i am newbie,have poor knowledge about multithread.
-
Re: VB Multithread Library (Generic Multithreader)
@ 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.
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
Krool
@ 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.
yes,i have change the app.path,but if i make to exe can not run.msgbox project error...if run in vb ide will be ok..my system is win7. 32. thanks. can you fixed ?put a project demo to me ?
-
Re: VB Multithread Library (Generic Multithreader)
-
Re: VB Multithread Library (Generic Multithreader)
I have got it to work.
What you Need to do is as following:
form-Level declarations:
Code:
Private AppPath As String, http As clshttp
Implements IThread '
During Form_Load:
Code:
Private Sub Form_Load()
AppPath = App.Path
Set http = New clshttp
New GetData function:
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
-
Re: VB Multithread Library (Generic Multithreader)
yes.your are right.now work ok.thanks
-
Re: VB Multithread Library (Generic Multithreader)
@ 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
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
Krool
@ 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
thanks ,the project is my test. I just want to test it stability.the program works fine,Thank you for your work
-
Re: VB Multithread Library (Generic Multithreader)
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..
-
Re: VB Multithread Library (Generic Multithreader)
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..
-
Re: VB Multithread Library (Generic Multithreader)
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>
-
Re: VB Multithread Library (Generic Multithreader)
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
wqweto
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>
"Out-of-process" is a perfect description for that case. Thanks
-
Re: VB Multithread Library (Generic Multithreading)
Included LinkSwitch /OPT:NOWIN98 on the VBCompiler which reduced the file size of the DLL from 48KB to 36KB
-
2 Attachment(s)
Re: VB Multithread Library (Generic Multithreading)
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
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
VBDevelopper
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:
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
the following:
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
-
Re: VB Multithread Library (Generic Multithreading)
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.
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
ChenLin
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.
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
Krool
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.
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
I'm using this. May I have this, please?
Yesterday's test was ADO data control, which has been tested.
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
Krool
You have a logic error, try instead of:
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
the following:
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
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
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
VBDevelopper
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.
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
Interface method when a thread's background procedure has been completed or canceled.
The Thread is already terminated (hThread = 0) when this method is called.
Code:
Public Sub Complete(ByVal Key As String, ByVal Data As ThreadData)
End Sub
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 StatusCallback(ByVal Key As String, ByRef Argument1 As Variant, ByRef Argument2 As Variant)
End Sub
-
Re: VB Multithread Library (Generic Multithreading)
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?
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
VBDevelopper
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.
-
Re: VB Multithread Library (Generic Multithreading)
but if there are the activeX:confused: because one needs to use other paths?
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
VBDevelopper
but if there are the activeX :confused: because one needs to use other paths?
FYI ActiveX EXE's can't be run without either being "installed" with administrator rights, or run the first time with administrator rights, where it registers it's interfaces.
Krool's DLL however can be used SxS, without the need for admin rights.
-
Re: VB Multithread Library (Generic Multithreading)
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
ChenLin
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
I'm using this. May I have this, please?
Yesterday's test was ADO data control, which has been tested.
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.
-
Re: VB Multithread Library (Generic Multithreading)
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>
-
Re: VB Multithread Library (Generic Multithreading)
Quote:
Originally Posted by
wqweto
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.
Added a note in thread's first post that P-Code will fail. So maybe it's more noticed for new users.
-
Re: VB Multithread Library (Generic Multithreader)
Quote:
Originally Posted by
Krool
Here is a solution to use the VBMThread11.DLL Registration-Free. (Side-by-side)
Keep in mind that this technology needs at minimum Windows XP SP2 or Windows Server 2003.
Big thanks goes to 'the trick' for the solution with "comInterfaceExternalProxyStub" in the manifest.
Tutorial:
The "Development" machine needs to register VBMThread11.DLL as usual and use the components for e.g. in a Std-EXE project.
The source project needs to include the Side-by-side resources. (see below)
Then on the "End user" machine you only need the VBMThread11.DLL and the .exe (Std-EXE project) on the same folder.
It will work then without any registration.
The source code of "VBMThread11SideBySide.res" is:
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<file name="VBMThread11.DLL">
<typelib tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}" version="1.0" flags="" helpdir="" />
<comClass clsid="{AAE10FA6-5E20-4FA7-9649-678DC3971353}" tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}" threadingModel="Apartment" progid="VBMThread11.Thread" description="" />
</file>
<comInterfaceExternalProxyStub
name = "_Thread"
iid="{71154E34-A914-4E30-A4BA-5CE94A6D9C46}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
</comInterfaceExternalProxyStub>
<comInterfaceExternalProxyStub
name = "__Thread"
iid="{403717A2-9E4E-4FEC-B77A-62DC68B9C294}"
proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
</comInterfaceExternalProxyStub>
<comInterfaceExternalProxyStub
name = "_ThreadData"
iid="{55A8AC17-7DB5-468D-93BD-86E8B97C53A5}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
</comInterfaceExternalProxyStub>
<comInterfaceExternalProxyStub
name = "_IThread"
iid="{68F61D7E-21CD-41E6-AFEC-C3820C6743D5}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
</comInterfaceExternalProxyStub>
<comInterfaceExternalProxyStub
name = "_IThreadStatusCallback"
iid="{09256C4A-7A89-40F6-BBEE-3D5445942C4A}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{1A02D9E1-9609-40B3-8AFE-727D8A144707}">
</comInterfaceExternalProxyStub>
</assembly>
In the attachment I have added the same as a compiled resource.
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".