I am trying to use ThreadPool, but it is giving me errors:
class test
{
public void testMethod1(bool param)
{
var something = !param;
}
public void testMethod2()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(testMethod1), true); //expected a 'void testMethod1(object) signature'
ThreadPool.QueueUserWorkItem(new WaitCallback(testMethod1(true))); //method name is expected
}
}
How to properly use ThreadPool?
The WaitCallback delegate expects a System.Object as it's argument. You would need to use that to pass in the value.
private void TestMethodWrapper(object param)
{
TestMethod1((bool)param);
}
public void TestMethod1(bool param)
{
var something = !param;
}
public void testMethod2()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(TestMethodWrapper), true);
}
This was the common pattern early on, but the current C# language allows more flexibility. For example, using a lambda is far simpler:
public void testMethod2()
{
ThreadPool.QueueUserWorkItem(o => testMethod1(true));
}
When calling using this last method, the compiler effectively creates the wrapper method for you.
ThreadPool.QueueUserWorkItem(_ => testMethod1(true));
Related
How could I wrap some code in brackets to do the following?
MyCustomStatement(args){
// code goes here
}
So that before the code in the brackets executes, it'll call a method and when the code in the brackets finishes executing it will call another method. Is there such a thing? I know it seems redundant to do this when I can simply call the methods before and after the code and all, but I simply was curious. I don't know how to word this exactly because I'm new to programming.
Thanks!
You can do this by storing the code in an abstract class that executes the "before" and "after" code for you when you call Run():
public abstract class Job
{
protected virtual void Before()
{
// Executed before Run()
}
// Implement to execute code
protected abstract void OnRun();
public void Run()
{
Before();
OnRun();
After();
}
protected virtual void After()
{
// Executed after Run()
}
}
public class CustomJob : Job
{
protected override void OnRun()
{
// Your code
}
}
And in the calling code:
new CustomJob().Run();
Of course then for every piece of custom code you'll have to create a new class, which may be less than desirable.
An easier way would be to use an Action:
public class BeforeAndAfterRunner
{
protected virtual void Before()
{
// Executed before Run()
}
public void Run(Action actionToRun)
{
Before();
actionToRun();
After();
}
protected virtual void After()
{
// Executed after Run()
}
}
Which you can call like this:
public void OneOfYourMethods()
{
// your code
}
public void RunYourMethod()
{
new BeforeAndAfterRunner().Run(OneOfYourMethods);
}
To literally achieve what you want, you can use a delegate:
Action<Action> callWithWrap = f => {
Console.WriteLine("Before stuff");
f();
Console.WriteLine("After stuff");
};
callWithWrap(() => {
Console.WriteLine("This is stuff");
});
This requires adding "weird syntax" to your blocks and an understanding of how delegates and anonymous functions in C# work. More commonly, if you're doing this within a class, use the technique demonstrated in #CodeCaster's answer.
This is a C#.net question for Objective-C developers who also work with C#.Net
As you know, Objective-C you can parse a method name to a Selector; and the method can also belong to an outside class.
I would like to be able to use this type of method in C#.Net as it would be a lot cleaner than creating loads of Events which can become messy and hard to manage.
If this is possible, how can I achieve this? Thank you!
Example:
public class Main
{
public void MyProcess(Callback toMethod)
{
// do some fancy stuff and send it to callback object
toMethod(result);
}
}
public class Something
{
public void RunMethod()
{
MyProcess(Method1);
MyProcess(Method2);
}
private void Method1(object result)
{
// do stuff for this callback
}
private void Method2(object result)
{
// do stuff for this callback
}
}
I don't know Objective-C, but I think you want something like this:
public class Main
{
public void MyProcess(Action<object> toMethod, object result)
{
// do some fancy stuff and send it to callback object
toMethod(result);
}
}
public class Something
{
public void RunMethod()
{
object result = new object();
MyProcess(Method1, result);
MyProcess(Method2, result);
}
private void Method1(object result)
{
// do stuff for this callback
}
private void Method2(object result)
{
// do stuff for this callback
}
}
You would have to use Delegates. Based on the code in your question, you would declare a delegate:
public delegate void MethodDelegate(object result);
The signature of the process method changes to the following:
public void MyProcess(MethodDelegate toMethod)
{
// do some fancy stuff and send it to callback object
toMethod(result);
}
And then you would call process
public void RunMethod()
{
MyProcess(new MethodDelegate(Method1));
MyProcess(new MethodDelegate(Method1));
}
I have these lines of code.
class Program
{
public delegate void printer();
public static void Method()
{
Console.WriteLine("Hello");
}
static void Main(string[] args)
{
printer del = delegate { Method(); };
del();
Console.ReadKey();
}
}
Now what do i call this statement printer del = delegate { Method(); };.
Surely it cant be called anonymous method because here i have a named method.
It's called an Anonymous method
Surely it can't be called anonymous method because here I have a named method
It's still an anonymous method, as #Daniel pointed out in the comments what your doing is instantiating an instance of the printer delegate by assigning a method with the same signature (which happens to be...an anonymous method). You could avoid using an anonymous method completely by doing:
Printer del = Method;
It's an anonymous delegate who's only function happens to be calling a named method.
It's an anonymous method. The inside of the method does call a named one but that doesn't change the fact that the outher method is anonymous.
You can easily see this when you would expand del:
class Program
{
public delegate void printer();
public static void MethodA()
{
Console.WriteLine("Hello");
}
public static void MethodB()
{
Console.WriteLine("World");
}
static void Main(string[] args)
{
bool x = true;
printer del = delegate
{
if (x)
{
MethodA();
}
else
{
MethodB();
}
};
del();
Console.ReadKey();
}
}
If you don't want to use a delegate you could do the same with an Action:
Action delA = () => MethodA();
delA();
Action points to a void returning method that takes no parameters.
It's an anonymous method, as the others have said.
You could also accomplish the same thing with this code:
Action del = () => Method();
del();
This way, you don't need to define the delegate and use the built-in Action type.
This would be the first time I'd use delegates in c# so please bear with me. I've read a lot about them but never thought of how/why to use this construct until now.
I have some code that looks like this:
public class DoWork()
{
public MethodWorkA(List<long> TheList) {}
public void MethodWork1(parameters) {}
public void MethodWork2(parameters) {}
}
I call MethodWorkA from a method outside the class and MethodWorkA calls MethodWork 1 and 2. When I call methodA, I'd like to pass some sort of parameter so that sometimes it just does MethodWork1 and sometimes it does both MethodWork1 and MethodWork2.
So when I call the call it looks like this:
DoWork MyClass = new DoWork();
MyClass.MethodA...
Where does the delegate syntax fit in this?
Thanks.
public void MethodWorkA(Action<ParamType1, ParamType2> method) {
method(...);
}
You can call it using method group conversion:
MethodWorkA(someInstance.Method1);
You can also create a multicast delegate that calls two methods:
MethodWorkA(someInstance.Method1 + someInstance.Method2);
For what you described, you don't need delegates.
Just do something like this:
public class DoWork
{
public void MethodWorkA(List<long> theList, bool both)
{
if (both)
{
MethodWork1(1);
MethodWork2(1);
}
else MethodWork1(1);
}
public void MethodWork1(int parameters) { }
public void MethodWork2(int parameters) { }
}
If you're just experimenting with delegates, here goes:
public partial class Form1 : Form
{
Func<string, string> doThis;
public Form1()
{
InitializeComponent();
Shown += Form1_Shown;
}
void Form1_Shown(object sender, EventArgs e)
{
doThis = do1;
Text = doThis("a");
doThis = do2;
Text = doThis("a");
}
string do1(string s)
{
MessageBox.Show(s);
return "1";
}
string do2(string s)
{
MessageBox.Show(s);
return "2";
}
}
Considering that all methods are inside the same class, and you call MethodWorkA function using an instance of the class, I honestly, don't see any reason in using Action<T> or delegate, as is I understood your question.
When I call methodA, I'd like to pass some sort of parameter so that
sometimes it just does MethodWork1 and sometimes it does both
MethodWork1 and MethodWork2.
Why do not just pass a simple parameter to MethodWorkA, like
public class DoWork()
{
public enum ExecutionSequence {CallMethod1, CallMethod2, CallBoth};
public MethodWorkA(List<long> TheList, ExecutionSequence exec)
{
if(exec == ExecutionSequence.CallMethod1)
MethodWork1(..);
else if(exec == ExecutionSequence.CallMethod2)
MethodWork2(..);
else if(exec == ExecutionSequence.Both)
{
MethodWork1(..);
MethodWork2(..);
}
}
public void MethodWork1(parameters) {}
public void MethodWork2(parameters) {}
}
Much simplier and understandable for your class consumer.
If this is not what you want, please explain.
EDIT
Just to give you an idea what you can do:
Example:
public class Executor {
public void MainMethod(long parameter, IEnumerable<Action> functionsToCall) {
foreach(Action action in functionsToCall) {
action();
}
}
}
and in the code
void Main()
{
Executor exec = new Executor();
exec.MainMethod(10, new List<Action>{()=>{Console.WriteLine("Method1");},
()=>{Console.WriteLine("Method2");}
});
}
The output will be
Method1
Method2
In this way you, for example, can push into the collection only functions you want to execute. Sure, in this case, the decision logic (which functions have to be executed) is determined outside of the call.
This question already has answers here:
Pass Method as Parameter using C#
(13 answers)
Closed 2 years ago.
I want to be able to pass a method as a parameter.
eg..
//really dodgy code
public void PassMeAMethod(string text, Method method)
{
DoSomething(text);
// call the method
//method1();
Foo();
}
public void methodA()
{
//Do stuff
}
public void methodB()
{
//Do stuff
}
public void Test()
{
PassMeAMethod("calling methodA", methodA)
PassMeAMethod("calling methodB", methodB)
}
How can I do this?
You need to use a delegate, which is a special class that represents a method. You can either define your own delegate or use one of the built in ones, but the signature of the delegate must match the method you want to pass.
Defining your own:
public delegate int MyDelegate(Object a);
This example matches a method that returns an integer and takes an object reference as a parameter.
In your example, both methodA and methodB take no parameters have return void, so we can use the built in Action delegate class.
Here is your example modified:
public void PassMeAMethod(string text, Action method)
{
DoSomething(text);
// call the method
method();
}
public void methodA()
{
//Do stuff
}
public void methodB()
{
//Do stuff
}
public void Test()
{
//Explicit
PassMeAMethod("calling methodA", new Action(methodA));
//Implicit
PassMeAMethod("calling methodB", methodB);
}
As you can see, you can either use the delegate type explicitly or implicitly, whichever suits you.
Use Action<T>
Example:
public void CallThis(Action x)
{
x();
}
CallThis(() => { /* code */ });
Or Func<>
Func<int, string> func1 = (x) => string.Format("string = {0}", x);
PassMeAMethod("text", func1);
public void PassMeAMethod(string text, Func<int, string> func1)
{
Console.WriteLine( func1.Invoke(5) );
}
Delegates are the language feature that you're going to need to use to accomplish what you're trying to do.
Here's an example using the code you have above (using the Action delegate as a shortcut):
//really dodgy code
public void PassMeAMethod(string text, Action method)
{
DoSomething(text);
method(); // call the method using the delegate
Foo();
}
public void methodA()
{
Console.WriteLine("Hello World!");
}
public void methodB()
{
Console.WriteLine("42!");
}
public void Test()
{
PassMeAMethod("calling methodA", methodA)
PassMeAMethod("calling methodB", methodB)
}
Building on what BrunoLM did, as that example was brief.
//really dodgy code
public void PassMeAMethod(string text, Action method)
{
DoSomething(text);
method();
Foo();
}
// Elsewhere...
public static void Main(string[] args)
{
PassMeAMethod("foo", () =>
{
// Method definition here.
}
);
// Or, if you have an existing method in your class, I believe this will work
PassMeAMethod("bar", this.SomeMethodWithNoParams);
}
c# .net2.0 - Let me show a detailed answer for the topic (pass-a-method-as-a-parameter).
In my scenario i'm configuring a set of System.Timers.Timer-s, each with a different _Tick method.
delegate void MyAction();
// members
Timer tmr1, tmr2, tmr3;
int tmr1_interval = 4.2,
tmr2_interval = 3.5;
tmr3_interval = 1;
// ctor
public MyClass()
{
..
ConfigTimer(tmr1, tmr1_interval, this.Tmr_Tick);
ConfigTimer(tmr2, tmr2_interval, (sndr,ev) => { SecondTimer_Tick(sndr,ev); });
ConfigTimer(tmr3, tmr3_interval, new MyAction((sndr,ev) => { Tmr_Tick((sndr,ev); }));
..
}
private void ConfigTimer(Timer _tmr, int _interval, MyAction mymethod)
{
_tmr = new Timer() { Interval = _interval * 1000 };
// lambda to 'ElapsedEventHandler' Tick
_tmr.Elpased += (sndr, ev) => { mymethod(sndr, ev); };
_tmr.Start();
}
private void Tmr_Tick(object sender, ElapsedEventArgs e)
{
// cast the sender timer
((Timer)sender).Stop();
/* do your stuff here */
((Timer)sender).Start();
}
// Another tick method
private void SecondTimer_Tick(object sender, ElapsedEventArgs e) {..}