 |
|
 |
I think information is provided in this article regarding Thread-Pool.
|
|
|
|
 |
|
 |
I am using VS2008.
Is this still a valid solution for a threadpool.
I have successfully created and tested the following delegate declaration
Public Delegate Function CreateStatsForRiskClassDelegate(ByVal arParam() As Object) As Integer
However when when I use the threadpool I get a Parameter count mismatch exception
System.Reflection.TargetParameterCountException was caught
Message="Parameter count mismatch."
Source="mscorlib"
StackTrace:
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at StressMastr.XYThreadPool.ThreadProc() in D:\Bin05\StressMastr\Utils\XYThreadPool.vb:line 66
Using the following to insert the item
Dim oParams(1) As Object
oParams(0) = oItem.Tag
oParams(1) = numHorizon.Value
gThreadPool.InsertWorkItem(oItem.Text, New CreateStatsForRiskClassDelegate(AddressOf oSC.CreateStatsForRiskClass), oParams, True)
Exception thrown in ThreadProc by this line
oWorkItem.m_oOutput = oWorkItem.m_pMethod.DynamicInvoke(oWorkItem.m_pInput)
On another subject
Is it possible to dequeue a specific item in the input Q. I want to add a dependancy group to the item structure and if an exception is thrown I want to delete all items with the same dependancy group.
TIA
Never underestimate the power of human stupidity
RAH
|
|
|
|
 |
|
 |
The paramter mismatch was caused by changing the target method to accept an array of objects instead of leaving the bloody thing alone.
Mycroft Holmes wrote: Public Delegate Function CreateStatsForRiskClassDelegate(ByVal arParam() As Object) As Integer
Gotchas
The target method needs to accept Object values in the declaration and to type them within the target method.
Each thread needs it's own connection othewise there is a clash of datareaders for executescalar.
Never underestimate the power of human stupidity
RAH
|
|
|
|
 |
|
 |
Hi, I opened this project in VB 2005 Express, it updated the code fine (I hope). But I have one problem I dont understand. Whatever kind of object I try to pass below (see: foo), it errors with: System.ArgumentException: Object of type 'System.String' cannot be converted to type 'System.Object[]'. Replace system.string above with the kind of object you pass. It errors on line: XYThreadPool.vb:line 56 Which is this line: oWorkItem.m_oOutput = oWorkItem.m_pMethod.DynamicInvoke(oWorkItem.m_pInput) a.test is a sub in the class Test. Public Sub Test(ByVal indata() As Object) ... End sub I cant see why I would get this error... String inherits object and should work, as far as I get it. It does work with foo=nothing, but is not really an option here. ******************* <code>Public t As New XYThreadPool Dim a As New Class1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim foo(0) As Object 'Dim b As String = "data 123 bla bla etc" 'Dim foo() As Object = {b} 'Dim mm As Object = Nothing 'foo(0) = New Object 'mm = New foobar("dsdas das d sa") 'foo(0) = CType(mm, foobar) 'foo(0) = b 'foo(0) = "test mmm 3235" 'foo(0) = New foobar("data 123 bla bla etc") 'foo(0) = New System.String("a", 10) t.InsertWorkItem("test", New DelegateTest(AddressOf a.Test), foo, False) End Sub</code> / BlackWand
|
|
|
|
 |
|
 |
Nevermind...
It was the required ParamArray which was tricky.
/ BlackWand
|
|
|
|
 |
|
 |
I want to insert bulk records into sql server database one by one using ado.net.But at time of lacks of record insertion program gets hang.So pls kindly provide help for same.
Chandrashekhar
|
|
|
|
 |
|
 |
Can someone give me an example only in VB ?
Thank you.
Daniele
|
|
|
|
 |
|
 |
Lets say I need to refresh workitems to begin a new batch of workitems. Would I then: StopThreadPool -> Sleep -> StartThreadPool(i.e. New batch worker items) Because here is my dilemma. I have several 'Books' of information (let's just say 30 Books) to process from a 'RackList'. Each 1 Book has 99+ Pages to Parse or process through. So here is what I look at doing: <code> Public Sub Begin(byval RackList as ArrayList) Thread.Sleep(3000) Dim myPool1 As New XYThreadPool Dim myPool2 As New XYThreadPool myPool1.StartThreadPool(3, 30) myPool2.StartThreadPool(20, 40) Thread.Sleep(3000) For x As Integer = 0 To RackList.Count - 1 Dim book1 As Book = Nothing Dim book2 As Book = Nothing Try book1 = CType(RackList(x), Book) For i As Integer = 0 To book1.Pages myPool1.InsertWorkItem(book1.Name, New ThreadAddDelegate(AddressOf ThreadAdd), New [Object](1) {book1, i + 1}, True) Thread.Sleep(100) If IsStopped Then myPool1.StopThreadPool() : myPool2.StopThreadPool() Next i For i As Integer = 0 To book1.Pages Dim obj1 As ThreadPoolWorkItem = Nothing While obj1 Is Nothing Thread.Sleep(100) obj1 = myPool1.ExtractWorkItem() End While RaiseEvent SendMessage(Nothing, obj1.m_sName) Thread.Sleep(50) If IsStopped Then myPool1.StopThreadPool() : myPool2.StopThreadPool() Next i Catch ex As Exception End Try Try book2 = CType(RackList(x + 1), Book) For i As Integer = 0 To book2.Pages myPool2.InsertWorkItem(book2.Name, New ThreadAddDelegate(AddressOf ThreadAdd), New [Object](1) {book2, i + 1}, True) Thread.Sleep(100) If IsStopped Then myPool1.StopThreadPool() : myPool2.StopThreadPool() Next i For i As Integer = 0 To book2.Pages Dim obj2 As ThreadPoolWorkItem = Nothing While obj2 Is Nothing Thread.Sleep(100) obj2 = myPool2.ExtractWorkItem() End While RaiseEvent SendMessage(Nothing, obj2.m_sName) Thread.Sleep(50) If IsStopped Then myPool1.StopThreadPool() : myPool2.StopThreadPool() Next i Catch ex As Exception End Try Thread.Sleep(100000) If IsStopped Then myPool1.StopThreadPool() : myPool2.StopThreadPool() Next x myPool1.StopThreadPool() myPool2.StopThreadPool() Thread.Sleep(3000) End Sub </code> TL Wallace
|
|
|
|
 |
|
 |
I was wondering how we could wait for all threads in your ThreadPool including those waiting in queue to be processed. I tested these lines of code, but it doesn't actually seem to work properly:
myPool.SetShutdownPause(-1);
mpPool.StopThreadPool();
And I also think that you should change this line (within StopThreadPool method):
If (m_nShutdownPause > 0) Then
to this:
If (m_nShutdownPause <= 0) Then
As you have supposed, only when the parameter passed to
SetShutdownPause mehtod is less than or equal to 0 we will wait for all threads to terminate(but you have done inversly in your code!!! )
And finally, through what I have read so far in other articles, Abort method is not that reliable, is it?
Good luck
I lock my house, I lock my car and I pull that zipper on my pants up several times a day for the sake of security.
|
|
|
|
 |
|
 |
Hello, Maysam. Thanks for your comments.
You probably misunderstood what I said. When implementing the StopThreadPool method, I am facing with two choices:
(a) To forcefully terminate each thread that is still executing.
(b) Leave such threads alone (they will terminate themselves when the work is done).
The current implementation is, the method will sleep for m_nShutdownPause milliseconds (or 200 milliseconds if m_nShutdownPause is too small). Then all remaining threads will be terminated forcefully by calling abort if m_nShutdownPause is greater than 0. Otherwise, abort will not be called at all.
So if you set m_nShutdownPause to -1, then it is possible that your thread will never be terminated (in case it never finishes its work). You either terminate a thread by force or not, there is no other way.
BTW, nice picture in your profile.
My articles and software tools
|
|
|
|
 |
|
 |
Yes, you are right! There are some circumstances in which I misunderstand somethings, and this is actually one of them
BTW, Yes, you are right! nice picture in my profile.
I lock my house, I lock my car and I pull that zipper on my pants up several times a day, just for the sake of security.
|
|
|
|
 |
|
 |
Thread pools are not something to be taken lightly. Writing it in VB.NET makes me even more nervous. Things that are wrong about this threadpool that'll make it fail: 1.) Using Monitor.Enter and Exit without protecting it with a Finally block. What if Dequeue() throws an exception? Monitor.Exit() never gets called and you have a dangling lock. Very bad. Why not use the SyncLock() keyword? It just wraps Monitor.Enter/Exit and handles the Finally problem. Or better yet, use C# and use the lock() keyword. 2.) Thread.Sleep() is a very poor way to wait threads. First because it'll kill battery-operated devices, second because it's not reliable. You should use things like Monitor.Wait() and Monitor.Pulse(). 3.) Your code for stopping the thread pool is broken and won't work very well under stress. Signaling them then waiting is horrible, not to mention killing them outright if they don't respond right away. Granted, you need a bail-out scenario, but you should have the user pass in a value whether they want the threads forcibly terminated. I would suggest that under normal conditions you definately DO NOT want this to happen because you'll hide potential deadlocks if you simply abort the threads. You need a semaphore to count the currently-running threads and an AutoResetEvent or ManualResetEvent to have the controller thread WaitOne() on the event and when the last thread decrements the Semaphore to 0, signal the event.
|
|
|
|
 |
|
 |
__daz wrote:
Thread pools are not something to be taken lightly. Writing it in VB.NET makes me even more nervous.
If your problem is with VB, then you may want to stay away from .NET altogether. If you search posts from the Lounge, someone provided evidence a few weeks ago that [Edit] Visual Studio.NET IDE and VB IDE share the same code [/Edit].
__daz wrote:
1.) Using Monitor.Enter and Exit without protecting it with a Finally block. What if Dequeue() throws an exception? Monitor.Exit() never gets called and you have a dangling lock. Very bad.
You are not paying attention to the documentation or to my code. The only possible way for the Dequeue operation to throw an exception is that the queue is already empty, which is impossible in my code.
__daz wrote:
3.) Your code for stopping the thread pool is broken and won't work very well under stress.
Again, if you read carefully, you will find out that the user can determine whether to end the active threads forcefully when the pool is shutdown.
I understand that you have strong opinions on how thread pool should be implemented and would like to see your code if you care to share.
Thanks for your input.
My articles and software tools
|
|
|
|
 |
|
 |
I'm sorry you're so misinformed. The IDE was a combination of C# and native C++. Ask Eric Gunnerson, PM of the Visual C# team who worked on the Visual Studio.NET 2002 and 2003 projects and saw the code. He frequently posts to microsoft.public.dotnet.languages.csharp and he will give you all the details.
As far as Monitor.Enter/Exit, the Dequeue was only one example. You use it incorrectly throughout your code and there are plenty of places where exceptions could possibly bubble and locks not get closed.
It's pretty ignorant to say it's "impossible" or "never". Irregardless, you should use Finally because you never know what unsuspecting maintenance programmer will get caught in your trap.
Why flirt with danger when you can simply use a feature that's BUILT INTO THE LANGUAGE called SyncLock which does exactly what you want and makes the code less complex.
Also, regardless of whether the user can select forced closure (which is a nice feature, thank you for implementing it), your looping-and-sleeping way of closing the pool is sketchy at best.
Please read some of these articles by one of the CLR designer who talks all about threading and you'll realize that threading and especially pools are far more complicated than you think they are:
Apartments and Pumping in .NET:
http://blogs.msdn.com/cbrumme/archive/2004/02/02/66219.aspx
Managed Blocking:
http://blogs.msdn.com/cbrumme/archive/2003/04/17/51361.aspx?Pending=true
Startup, Shutdown and related matters:
http://blogs.msdn.com/cbrumme/archive/2003/08/20/51504.aspx
|
|
|
|
 |
|
 |
__daz wrote:
I'm sorry you're so misinformed. The IDE was a combination of C# and native C++.
Well, I may be misinformed but you don't need to be sorry about it. The native C++ you mentioned could be the same code that was used to build the VB IDE, because the Visual Studio.NET IDE windows have identical class names as VB IDE windows.
__daz wrote:
As far as Monitor.Enter/Exit, the Dequeue was only one example. You use it incorrectly throughout your code and there are plenty of places where exceptions could possibly bubble and locks not get closed.
You need to give me one specific example where I misused it (it shouldn't be too hard since you said I did it wrong throughout my code).
__daz wrote:
Irregardless, you should use Finally because you never know what unsuspecting maintenance programmer will get caught in your trap.
Come on, be reasonable, nobody can write code that prevents maintenance guys from screwing up.
__daz wrote:
Please read some of these articles by one of the CLR designer who talks all about threading and you'll realize that threading and especially pools are far more complicated than you think they are.
The links you included talked about threads but are not directly related to thread pool implementation.
In fact, I have less respect for the CLR designers in Microsoft than you do, because they are employees of a big corporation just like me, plus they can talk about anything they want without showing you the source code of CLR. I don't mean that I disrespect any of them, I just don't feel the need to respect them at this time.
My articles and software tools
|
|
|
|
 |
|
 |
"because the Visual Studio.NET IDE windows have identical class names as VB IDE windows."
You mean as the Visual Basic.NET IDE, or as the VB6 IDE?
So you're saying that because the windows have the same name as the VB6 IDE, it has to be coded in VB? What an absurd assertion.
Regardless, simply ask Eric Gunnerson:
"Willy is correct. The bulk of the IDE is written in C++, though parts - such
as the property grid - are written in C#.
While we do try to eat our own dog food whenever possible, when we started
working on .NET, you couldn't write any .NET code because the runtime,
frameworks, and compilers weren't finished enough to allow that. In the
future, you can expect to see more of VS.NET move over to managed code."
http://groups.google.com/groups?q=Gunnerson+Visual+Studio+written+in+C%23&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=uBnHXZiPCHA.2304%40tkmsftngp12&rnum=1
Here's his weblog:
http://weblogs.asp.net/ericgu
"You need to give me one specific example where I misused it (it shouldn't be too hard since you said I did it wrong throughout my code)."
How about everywhere? You should never use Monitor.Enter/Exit except in very specific circumstances. For all other uses, use SyncLock() or lock() (C#). Another bonus of this, besides the more robust code, is that the compiler will enforce that you not lock on a value type.
Look, you can make arguments all day why you should use inline-assembly to increment an integer value, but at the end of the day, the *best* and most well-respected way to do locking is to use the built-in keywords to do it.
Or at least, for god's sake, use a Try/Catch once in awhile.
"The links you included talked about threads but are not directly related to thread pool implementation. "
You'd still be wise to read them. In fact, the Apartment and Pumping is a great deal about how pooling threads should work (pumping) and how to properly deal with groups of threads, etc.
|
|
|
|
 |
|
 |
__daz wrote:
How about everywhere? You should never use Monitor.Enter/Exit except in very specific circumstances ...
Or at least, for god's sake, use a Try/Catch once in awhile.
For you information, I did use try/catch/finally blocks in the same file, there is no need to tell me something that I already know.
Your original post pointed out a place in my code where you think unhandled exception could break my program, I already explained that it is not going to happen. My code was carefully written to avoid unhandled exceptions, if you disagree with this you are welcome to give your argument based on fact.
VB.NET and C# provide almost the same capability, you need to get over with the differences in syntax and not be misled by self claimed experts.
My articles and software tools
|
|
|
|
 |
|
 |
Xiangyang Liu wrote:
Your original post pointed out a place in my code where you think unhandled exception could break my program, I already explained that it is not going to happen. My code was carefully written to avoid unhandled exceptions, if you disagree with this you are welcome to give your argument based on fact.
My argument is based on fact. The fact is, it's not good to use Monitor.Enter/Exit except in very specific and special circumstances. For every other purpose you should use SyncLock() or lock().
Saying that you've handled every exception may or may not be correct, but it's a red herring, it's irrelevant because your code is now polluted with a non-standard "hacky" style and I think most expert programmers would agree. It's like saying that you should always use do...while instead of while(). Sure, there are special and specific times when do...while is necessary, but by-and-large, you should stick to using while() in all the rest of the cases.
It's a matter of defensive programming and clean style. You can argue all day long, it doesn't change that fact.
VB.NET and C# provide almost the same capability, you need to get over with the differences in syntax and not be misled by others.
I get sad when I hear this. I've been unfortunate in having to work on 3 VB.NET contracts in a row and I can tell you, being an expert in the C# field, that while VB.NET and C# share about 80% of similar functionality, VB.NET is a terrible language to maintain because of it's verbosity (which makes it difficult to see the code from the language) and because most VB.NET programmers are junior and code erratically and ineffeciently (as we've seen demonsrated here again).
The truth is, there's no defense for VB.NET. People who willing use VB.NET either a.) don't know better (bad excuse), are too scared to go to a real language (C# or MEC++), or are too stubborn or set in their ways to change.
None of those excuses are valid and only contribute to more VB.NET pollution and poorly-written code like this ThreadPool and it doesn't advance the cause of the spread of well-written .NET code.
I'm not going to post here anymore. You've yet to provide any valid arguments in defense of your code. Rather than admitting you're doing things in non-standard and dangerous ways, let alone that your code is broken and will cause race conditions and deadlocks under stress and especially on hyperthreaded or multi-proc boxes, you try to defend it which suggests that you don't know what the hell you're doing. I suggest you get a book on Multithreading.
Manning Publications has a book called ".NET Multithreading" by Alan Dennis
http://www.amazon.com/exec/obidos/tg/detail/-/1930110545/102-2594785-6575319?v=glance
I was one of the technical reviewers on this book as well as Chris Brumme (one of the CLR designers that I was posting links from in the last post), and I'm quoted on the back of it
|
|
|
|
 |
|
 |
__daz wrote:
My argument is based on fact. The fact is, it's not good to use Monitor.Enter/Exit except in very specific and special circumstances. For every other purpose you should use SyncLock() or lock().
Saying that you've handled every exception may or may not be correct, but it's a red herring, it's irrelevant because your code is now polluted with a non-standard "hacky" style and I think most expert programmers would agree. It's like saying that you should always use do...while instead of while(). Sure, there are special and specific times when do...while is necessary, but by-and-large, you should stick to using while() in all the rest of the cases.
It's a matter of defensive programming and clean style. You can argue all day long, it doesn't change that fact.
Your argument is not bad for a beginners' programming class, however the real experts or self-claimed experts do things differently all the time. How do I know? Check the source code from Microsoft. I have Visual Studio 6.0 on my workstation, a simple search for the text ".Lock" will yield a lot of code in MFC, ATL, etc. The code has one thing in common, that is using Lock and Unlock statements to contain a block of code without handling exceptions, which is very bad according to your standard. A simple explanation for writing code this way, I think, is that the programmer knows there won't be any exception.
Again, if you can find a line of my code (from source included with this article) that will cause unhandled exception, I will make the necessary correction immediately and thank you for it, I won't be interested in your how to program speech or the promotion of your friend's book.
__daz wrote:
I'm not going to post here anymore. You've yet to provide any valid arguments in defense of your code. Rather than admitting you're doing things in non-standard and dangerous ways, let alone that your code is broken and will cause race conditions and deadlocks under stress and especially on hyperthreaded or multi-proc boxes, you try to defend it which suggests that you don't know what the hell you're doing. I suggest you get a book on Multithreading.
I think your attack on my coding skill is not fair and not based on fact, but I don't really mind because I have seen worse. This world is full of people who think they are the best, some of them are a lot more convincing than you.
Have a nice day.
My articles and software tools
|
|
|
|
 |
|
 |
__daz wrote:
Manning Publications has a book called ".NET Multithreading" by Alan Dennis
http://www.amazon.com/exec/obidos/tg/detail/-/1930110545/102-2594785-6575319?v=glance
I was one of the technical reviewers on this book as well as Chris Brumme (one of the CLR designers that I was posting links from in the last post), and I'm quoted on the back of it
What's so great about this book? A book review on Amazon.com:
"For hard core programmers, the book is pretty useless and won't provide any insight."
|
|
|
|
 |
|
 |
There was also a review like this:
"The book gives a good explanation on .NET Threading."
This book isn't intended for long time multithreaded programming experts, it's intended for people who are just stepping into this realm like the author of this codeproject article.
He doesn't even understand the basics of threading and he should read this book or one like it. If he's using Sleep()s and counters all over the place, he missed the boat somewhere.
|
|
|
|
 |
|
 |
__daz wrote:
There was also a review like this:
"The book gives a good explanation on .NET Threading."
Reviews from friends and family members don't mean much, you know. If you want to promote a book or an article or a blog, there are better places to do it.
__daz wrote:
He doesn't even understand the basics of threading and he should read this book or one like it.
Let's get this straight. You initially pointed out specfic places where my code could break in addition to some general attacks. I don't have a high opinion of you and your friends' views on how programming should be done. I examined at the specific code you were talking about, it turns out there is no problem.
Now you insist on my code will be broken everywhere and I don't know the basics of multithreading. Ok, that's fine with me. I already have a pretty good impression on what kind of "experts" you are. I am not writing articles to please everyone and will not stop writing when you or someone else doesn't like it.
It just amazes me how quickly people can abandon objectivity and fairness when their ego is involved.
My articles and software tools
|
|
|
|
 |
|
 |
You should talk of ego. Someone who refuses to even admit one wrongdoing in the face of criticism. The better part of valor would be to admit that perhaps your code could be better and no one is ever truly a master of multithreaded programming and something could always be better and invite suggestions from the community on how to make your code robust.
Instead, you make foolish 1st year CS student remarks like "An exception can never be thrown from here".
In light of specific criticisms such as the Thread.Sleep problem, you even refuse to acknowledge it. Seriously, get a book on multithreading. ANY multithreading book. I don't care, ANY of them should teach you the basics and hopefully illustrate why your code is so wrong and a very poor example to be posting on a public site like this.
If it were an academic example to invite community criticism and participation, that's one thing, but when subjected to more educated peer review, you even refuse to acknowledge that there could be the SLIGHTEST POSSIBILITY that there's a problem.
Have you ever heard of Monitor.Wait/Pulse/PulseAll? What about SyncLock() or lock()?
Seriously, when you've worked on dozens of major .NET applications for dozens of clients under various circumstances and get paid to do it and you witness what code like this can do, you really shouldn't be damaging the community by inviting people to use this.
I shutter at all the people that may have downloaded and used this code in their applications, applications which, when subjected to stress will die horribly, or kill batteries in mobile laptops and the like, etc.
The blind ignorance from the VB.NET is staggering. And no, it's not just syntactical differences, it's the quality of the code and the professionalism/experience of the coder and so far, everyone I've met that has willing chosen VB.NET over C# is a junior programmer that really doesn't know what the heck they're doing and can't even address basic OO problems/principles. Most VB.NET guys I know can't even tell you what Polymorphism means.
And then here, we have someone who refuses to even use what little syntactical sugar VB.NET offers in the SyncLock() keyword... it boggles the mind the level of ignorance and harm people like you are doing to the community.
Why do you think VB got such a bad rap? Because people who think the code is easy to write crank out horrible, buggy, and dangerous apps, that's why.
Boggling...
|
|
|
|
 |
|
 |
__daz wrote:
Instead, you make foolish 1st year CS student remarks like "An exception can never be thrown from here".
On the other hand, you insist that my code will break everywhere and yet refuse to identify what exception could be thrown at which place. The target (my code) is out there (and not moving by the way), all you need to do is shoot (find one line and name one possible exception), if you missed the target (as you have), try again. Is that too hard for you?
As to the points that I should not use Monitor.Enter, Thread.Sleep, and VB.NET in general, I don't think it is an argument worths making, especially to a close minded "expert" like you. I am not really a VB only developer, you can look at my articles and code right here, my skills and experiences are beyond people like you who get their knowledge from hastily written tech books and self promoting blogs.
No, I am not asking a chance to criticize your code. Frankly, I don't believe you have done anything that worths criticizing.
My articles and software tools
|
|
|
|
 |
|
 |
Go on guyz, I found talk more interesting than code.
Man having 1 bit brain with parity error
|
|
|
|
 |
|