|
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.
|
|
|
|
|
This is my code
Form1
public ToolStrip CheckboxPublicName<br />
{<br />
get<br />
{<br />
return this.timeToolStripMenuItem;<br />
}<br />
}
Form2
private void Time_KeyDown(object sender, KeyEventArgs e)<br />
{<br />
if (e.KeyData == Keys.Escape)<br />
{<br />
this.Visible = false;<br />
Form1.CheckboxPublicName.Checked = false;<br />
}<br />
}
And my errors are
form1
Error 1 Cannot implicitly convert type 'System.Windows.Forms.ToolStripMenuItem' to 'System.Windows.Forms.ToolStrip' C:\Users\Kyle\documents\visual studio 2010\Projects\Gadgets\Gadgets\Form1.cs 41 24 Gadgets
form2
Error 2 An object reference is required for the non-static field, method, or property 'Gadgets.Form1.CheckboxPublicName.get' C:\Users\Kyle\documents\visual studio 2010\Projects\Gadgets\Gadgets\Time.cs 130 17 Gadgets<br />
Can anyone please help me?
|
|
|
|
|
systemerror121 wrote: {
get
{
return this.timeToolStripMenuItem;
}
You are trying to return a Toolstrip menu item where as your return type is ToolStrip.
That is why you are getting an error.
|
|
|
|
|
Thank you very much I fixed it, but what do you think I should do for the 2nd error?
Form1.CheckboxPublicName.Checked = false;
Error
Error 1 An object reference is required for the non-static field, method, or property 'Gadgets.Form1.CheckboxPublicName.get' C:\Users\Kyle\documents\visual studio 2010\Projects\Gadgets\Gadgets\Time.cs 130 17 Gadgets
|
|
|
|
|
systemerror121 wrote: Error 2 An object reference is required for the non-static field, method, or property 'Gadgets.Form1.CheckboxPublicName.get' C:\Users\Kyle\documents\visual studio 2010\Projects\Gadgets\Gadgets\Time.cs 130 17 Gadgets
Its because (I think) that "CheckboxPublicName" is not static, so trying to access it from the class "Form1" (unless its an object then you need to change your naming convention) wont work.
Try Form1 form = new Form1(); somewhere and then you can get the reference for the property form.CheckboxPublicName :P
Also instead of :
if (e.KeyData == Keys.Escape)
{
this.Visible = false;
Form1.CheckboxPublicName.Checked = false;
}
try this for a better code structure:
bool result = (e.KeyData == Keys.Escape);
Visible = form.CheckboxPublicName = result;
|
|
|
|
|
I wanna do something like
<br />
bool result = (e.KeyData == Keys.Escape);<br />
Visible = form.CheckboxPublicName = result;
But I wanna Keep
if (e.KeyData == Keys.Escape)<br />
{<br />
<br />
}
that border. and I don't really understand the
Visible = form.CheckboxPublicName = result;
Part, I want the toolstipitem to be unchecked not visible
|
|
|
|
|
You could make the property in form 1 "public static" so that you can use "Form1.CheckboxPublicName"
Use your original code instead of mine if its easier to understand
|
|
|
|
|
For the second part of your question: This is the wrong approach. Form2 should NOT be touching controls in Form1 at all.
Instead, assuming Form1 instanciates Form2 , Form1 should subscribe to an event raised by Form2 .
In Form1
form2.RequestUncheckPublicName += form2_RequestUncheckPublicName;
private void form2_RequestUncheckPublicName(object sender, EventArgs e)
{
}
In Form2
public event EventHandler RequestUncheckPublicName;
private void Time_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Escape)
{
Visible = false;
OnRequestUncheckPublicName(EventArgs.Empty);
}
}
protected virtual void OnRequestUncheckPublicName(EventArgs e)
{
EventHandler eh = RequestUncheckPublicName;
if(eh != null)
eh(this,e);
}
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)
|
|
|
|
|
DaveyM69 wrote: EventHandler eh = RequestUncheckPublicName;
if(eh != null)
eh(this,e);
+5 for showing the correct way to do this, ensuring that the handler has not been dereferenced between the null check and the actual raising of the event.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Ok this is the last error and if you fix it I will finally be done with this
code
public static ToolStripMenuItem CheckboxPublicName<br />
{<br />
get<br />
{<br />
return this.timeToolStripMenuItem;<br />
}<br />
}
Location Of Error
return this.timeToolStripMenuItem;
The Error
Error 1 Keyword 'this' is not valid in a static property, static method, or static field initializer C:\Users\Kyle\documents\visual studio 2010\Projects\Gadgets\Gadgets\Form1.cs 41 24 Gadgets<br />
|
|
|
|
|
That's because this can only be used in an instance, it cannot be used in a static property.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Yeh but when I take the static off I get this error at this line
Form1.CheckboxPublicName.Checked = false;
Error 1 An object reference is required for the non-static field, method, or property 'Gadgets.Form1.CheckboxPublicName.get' C:\Users\Kyle\documents\visual studio 2010\Projects\Gadgets\Gadgets\Time.cs 130 17 Gadgets
|
|
|
|
|
That's because Form1 is the name of the form, and not the instance you are referring to. As has been pointed out to you many times now, the approach you are choosing here is very poor form, and not to be chosen. You have been told that the best method is to use a delegate/event - follow that pattern instead as it is a much better OOP design.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Seriously, quit trying to access controls on Form1 from Form2 . It's not any easier than doing things the correct way and ends up messy. Trust me, drop that idea now... really!
Consider the following - it may not apply right now, but if you continue with programming you can be sure it will one day very soon.
Imagine you are developing a new class/control that you want to reuse across applications, and maybe even sell. In your use of this class, depending on a result you want to disable certain controls.
You could pass the controls to your class in a constructor or via a property/method - sounds good? No! If you want to reuse your class elsewhere, or others (customers) use it - it just isn't going to work without those controls which may not be relevant to their useage. So your class is broken. It will end up having to be re-written, or in the case of customers - refunds given.
Worse still, you could attempt the method you are trying, and access public static fields/properties on the object that owns the controls. What if they don;t exist? Again, your class is just plain broken.
However, you could adopt the same principles used by MS and all the others. When they developed for example the Button control they had no idea what you would do with it and certainly had no knowledge of the classes/objects that you would use it with, but still it works perfectly without issues. They provided a few properties to control it's appearance etc, and the most important thing - a Click event. Now you handle that event easily and everything is good in the world, yet Button has no knowledge of your classes/objects that are using it and it never should have.
Do the same, Form2 should let the world and all their relatives/friends know that something has happened (an event) that they may want to react to. If they are interested they can opt to listen for this event by adding a handler and respond accordingly. In your case this is Form1 that should handle an event from Form2 and only Form1 should do the thing with the menu item.
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)
|
|
|
|
|