|
Do you mean something like this?
void Post(MethodInvoker methodInvoker)
{
Post(new SendOrPostCallback((object useless) => { methodInvoker(); }));
}
Ok it isn't really a conversion.. but afaik that isn't possible anyway
edit: nevermind, if this was what you meant you wouldn't have asked..
|
|
|
|
|
harold aptroot wrote: if this was what you meant you wouldn't have asked
Well it does what I asked so I guess it was! Not being a Linqy kind of guy I have nor really used lambda expressions so I'm off to work out how/why this works and to see if can be done without the lambda
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier.
Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
Well, you could easily do it with a normal anonymous method:
void Post(MethodInvoker methodInvoker)
{
Post(delegate (object useless) { methodInvoker(); });
}
Or you could go for Pain and do it the manual way:
class HolderThingy
{
public MethodInvoker methodInvoker;
public void Invoke(object useless)
{
methodInvoker();
}
}
void Post(MethodInvoker methodInvoker)
{
HolderThingy holder = new HolderThingy();
holder.methodInvoker = methodInvoker;
Post(new SendOrPostCallback(holder.Invoke));
}
|
|
|
|
|
Cool
Is there anyway to do it using the null keyword instead of
object useless ?
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier.
Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
Not that I know of.. it has to match the method signature of SendOrPostCallback , so you need an argument of type object .
Why do you want to use null ?
|
|
|
|
|
no particular reason, useless is null anyway so it's no overhead.
Many thanks, credits are in the code pointing here
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier.
Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
You're welcome, and thanks
|
|
|
|
|
Hi Guys
I was working on a new class to simplify my code for multicore apps, but I stumbled on some difficulties...
I have already written code to exploit a dualcore and a quadcore, but only i a static fashion.
What I would like the class to do is, accept a method by means of a delegate and some arguments.
Then the class should check the number of cores and start the same number of threads, each with the subset of the arguments.
Let me clarify this... Suppose I have 20 images and I want to make all of them grayscale. I could assign every core a diiferent set of images to work on, since these operations do not interfere with eachother. As I said, I have already made a similar thing for dualcore, but I want to let the class sort this out by itself, so that in theory even a 99-core is supported.
The difficulties I'm having are more concerned with the delegates and arguments that need passing. This is what I have at the moment. Consider this pseudo-code because I think it's filled with errors
private static List<Thread> threads = new List<Thread> (0);
private static List<ThreadMethod> methods = new List<ThreadMethod>(0);
public delegate void xCO_Method(); delegate void CallBack(Thread T);
static private xCO_Method Method; static private CallBack CallBackMethod;
public static void Start(xCO_Method method, object[] args)
{
int cpu = System.Environment.ProcessorCount;
Method = method;
CallBackMethod = new CallBack(Completed);
for (int i = 0; i < cpu; i++)
{
methods.Add(new ThreadMethod());
threads.Add(new Thread(methods[i].Work));
threads[i].Name = i.ToString();
}
foreach (Thread T in threads)
T.Start(args[i]);
}
private class ThreadMethod
{
public object[] Result;
public void Work()
{
Method.Invoke(args);
CallBackMethod.Invoke(Thread.CurrentThread);
}
}
private static void Completed(Thread T)
{
Console.WriteLine("Thread " + T.Name + " ended");
}
Basically I want to prevent having to write a bunch of overloads and delegates for all kinds of methods.
But perhaps there is a better way.
Thanks
|
|
|
|
|
Why not just use the ThreadPool?
|
|
|
|
|
I have little to no experience with the ThreadPool. But after reading your reply, I did some googling and it really fits my needs at a first glance. I will give it a shot. Thank for the info. I'll let you know how it turns out. I just got so accustomed to using threads that I stopped looking for other solutions I guess...
edit:
I found this link
http://msdn.microsoft.com/en-us/library/3dasc8as%28VS.80%29.aspx[^]
Now the only one questions remains...
How can I give the class a list of methods which it should execute with the corresponding arguments.
But I want to do this in a generic way. Give a list of objects or classes and specify which method should be run, with which arguments it should use. I tried delegates and params, but this is getting me nowhere...
modified on Saturday, August 21, 2010 12:36 PM
|
|
|
|
|
Steven Solberg wrote: How can I give the class a list of methods which it should execute with the corresponding arguments.
But I want to do this in a generic way. Give a list of objects or classes and specify which method should be run, with which arguments it should use. I tried delegates and params, but this is getting me nowhere...
I'm not exactly sure what you mean..
|
|
|
|
|
Sorry about that
What I mean is the following;
The basic thing I want to accomplish is dividing a repetitive task into smaller fragments, so each core can work on it. Finishing the work faster than when only one core is used.
This 'work' can be about anything; Invoking a method on an image, a method on a self-defined class, ...
So what would be ideal for me would be something like this: DoWork(list<bitmap> bmps, method which_method, object argument_for_the_method)
This could be saving a list of bitmaps to disk, or resizing, anything... The list doesn't hve to be a list of bitmaps either.
I however can't figure out how to make a delegate or class which can support methods with and without return types and different lengths of parameters. And making a delegate for each different set of possibilities doesn't seem like an option either.
|
|
|
|
|
The best way I can think of now is using the semi-new type inference for generic method arguments and make overloads of the delegate only for the different numbers of arguments. Microsoft already did something like that in some newer .NET version, I'm not sure where exactly it was introduced, I'm guessing 3.5..
Does that help?
|
|
|
|
|
It certainly gives me a place to start. I will check out that type inference you mentioned.
Thanks
|
|
|
|
|
I was thinking about something like this:
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<T1, T2, T3, T4, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
public delegate TResult Func<T1, T2, T3, T4, T5, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
public delegate TResult Func<T1, T2, T3, T4, T5, T6, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
When you use them, you won't have to say new Func<type1, type2, type3 .. >(args) , at least not since VS08 (this kind of type inference does not work yet in VS05)
|
|
|
|
|
That's exactly what I needed
I assume the keyword TResult is arbitrary?
|
|
|
|
|
Steven Solberg wrote: I assume the keyword TResult is arbitrary?
Yes (it's not even a keyword), as are T1 T2 etc and arg1 arg2 etc
|
|
|
|
|
Hmmm, I noticed that I still have to specify the type in design-time.
public static void Start(List<Foto> objects, Func<...> method)
Is there a way to leave the ... undefined and let the function sort it out in run-time?
|
|
|
|
|
Ah yes, that happens, well you could give the generic parameters to Start as well and then it should work again (it usually does)
And you'd have to overload Start for every different kind of Func you want to use, too..
It's not perfect..
|
|
|
|
|
Alright I figured it out. Fresh knowledge... mmmmm
This was all stuff we had to know for our exam C++ this year. Freakin syntax...
Thanks with the generic stuff, I think I'll be alright now.
|
|
|
|
|
You're welcome
|
|
|
|
|
I do not really agree with the simple concept of launching all the jobs on the ThreadPool at once. AFAIK the ThreadPool has a dynamic number of threads at its disposal, and will launch more threads (at a speed of 2 new ones per second) when queued jobs remain too long in the queue (that seems true for client Windows, and probably is different on server Windows). The potential problem I foresee with that is, it does not care about the number of cores, so given enough work you will end up with many more threads than there are cores, and that in turn is likely to result in bad performance, due to either memory bandwidth limitations or cache trashing (data needlessly going in and out all the time as threads get switched out of fairness by the Windows kernel).
So what I suggest, assuming lots of work are (or could be) available: create a loop that launches the jobs on the ThreadPool, however rather than launching them all at once, let it wait once N jobs are outstanding, N probably being equal to the number of cores.
A further optimization may take into account that, on some CPUs, not all cores are equal. For instance, the cores on core i5 and i7 are basically paired (using hyperthreading), whereas AFAIK Xeon cores always are individual cores. So you might go for twice as many/half as many outstanding jobs depending on CPU characteristics.
|
|
|
|
|
I agree with you entirely and so I already planned to do that
I didn't plan on lauching a load of tasks on the threadpool, however my explanation of the problem may suggest that...
I only plan on splitting the amount of work over the available amount of cores. This I why I need repetitive tasks. Mostly methods that are invoked on a list of objects. The method accepts this list as an argument and processes this list. Now the idea was to split this list in the number of cores and run the method simultaneously across multiple cores, each with its subset of the original list. So the number of threads launched will always be the number of available cores, never more. At least if I can help it. Anyway who uses this class, should manage that by themselves.
|
|
|
|
|
You could split the job list into N smaller job lists and launch one thread for each; the risk now is one core gets a lot of easy jobs and finishes early, while another gets big jobs and takes much longer.
The alternative is to let the threads pull the next job from the single job list each time they are ready to handle one; this obviously requires a lock on the list, however it is the winning strategy for all but the smallest jobs. If the jobs are many but tiny, you should mix the strategies, i.e. statically aggregate a number of small jobs into bigger jobs, then assign those dynamically.
|
|
|
|
|
Most of the jobs require the same amount of time. The most of these jobs are concerned with image processing and searching lists. I know the duration of a job will vary with the size of the image, but I don't really mind 3 threads finishing while a 4th one takes longer. It's about the raw gain. As for the list searching it will be more a scenario of the 4 threads competing against eachother, the first one who finishes wins. Example: I need to search a list where the ID is 25. I can search the list start to end on one thread. But since I know this ID is unique (derived from database), I can also split the list and let each thread search. The first one returning a non-null value has found it, discard other threads.
|
|
|
|
|