Two questions about AsyncCallback and IAsyncResult pattern - c#

Two questions on the callback pattern with AsyncCallback and IAsyncResult.
I changed the question with a code example:
using System;
using System.Collections.Generic;
using System.Text;
namespace TestAsync
{
class Program
{
private static Wrapper test = new Wrapper();
static void Main(string[] args)
{
test.BeginMethod("parameter 1", "parameter 2", Callback);
Console.ReadKey();
}
private static void Callback(IAsyncResult ar)
{
string result = test.EndMethod(ar);
}
}
public interface ITest
{
IAsyncResult BeginMethod(string s1, string s2, AsyncCallback cb, object state);
string EndMethod(IAsyncResult result);
}
public class Wrapper
{
private ITest proxy = new Test();
public void BeginMethod(string s1, string s2, AsyncCallback cb)
{
proxy.BeginMethod(s1, s2, cb, proxy);
}
public string EndMethod(IAsyncResult result)
{
return ((ITest)(result.AsyncState)).EndMethod(result);
}
}
public class Test : ITest
{
private string WorkerFunction(string a, string b)
{
// "long running work"
return a + "|" + b;
}
public IAsyncResult BeginMethod(string s1, string s2, AsyncCallback cb, object state)
{
Func<string, string, string> function = new Func<string, string, string>(WorkerFunction);
IAsyncResult result = function.BeginInvoke(s1, s2, cb, state);
return result;
}
public string EndMethod(IAsyncResult result)
{
return (string)(result.AsyncState);
}
}
public delegate TResult Func<T1, T2, TResult>(T1 t1, T2 t2);
}
BEGIN EDIT
I am beginning to see what is going on.
I have mixed up a WCF async pattern and a normal async pattern.
In WCF one uses a proxy and the Begin- and EndMethod must be passed the proxy and not the function delegate. In the WCF case the casting works, in the normal case not.
WCF uses the [OperationContract(AsyncPattern = true)] attribute probably to enforce a somewhat different pattern.
END EDIT
Why the error on the line return (string)(result.AsyncState); ?
Exactly the same pattern in production code is ok.
Secondly, why can I not debug code in BeginMethod of class Test?
I can only break in WorkerFunction.

Let me give you this sample code to make things a bit clear. Please create a new console app and use this
public class Test
{
private int WorkerFunction(string a, string b)
{
//this is the guy that is supposed to do the long running work
Console.WriteLine(a);
Console.WriteLine(b);
return a.Length + b.Length;
}
private void MyCallBack(IAsyncResult ar)
{
Func<string, string, int> function = ar.AsyncState as Func<string, string, int>;
int result = function.EndInvoke(ar);
Console.WriteLine("Result is {0}", result);
}
public void CallMethod()
{
Func<string, string, int> function = new Func<string, string, int>(WorkerFunction);
IAsyncResult result = function.BeginInvoke("param1", "param2", MyCallBack, function);
}
}
class Program
{
static void Main(string[] args)
{
Test test = new Test();
test.CallMethod();
}
}
As you can see the callback function (MyCallBack) gets an IAsyncResult object passed back to it. It is this IAsynchResult object whose AyncState gives you the original object you had passed in the BeginInvoke method call. In this case (and as a general practice) you pass in the delegate itself as the object (which was the variable called "function").
One the callback was called, I then got the original delegate object back by quering the ar.AsyncState, I then called EndInvoke on it to get back the result.
As for the breakpoint not being hit, I am afraid I need some more information on it. What exactly do you mean? Where is this Console.WriteLine statement?
NEW RESPONSE
OK here is my version of your code. Basically no matter where you call the EndInvoke from, you need to call it on the actual delegate object (in your case the "function" variable you instantiate, passing it the actual IAsyncResult object). The code you have is trying to mask this facility however I must say there are less complicated ways of doing this. I will be more than happy to write a wrapper of sorts for you if you wish. For now I am simply giving you your code back with my small addition in it, that should make it work. Since you are using class level variables hence I am forced to use one myself. This is not really thread safe at the moment. But here goes
using System;
using System.Collections.Generic;
using System.Text;
namespace TestAsync
{
class Program
{
private static Wrapper test = new Wrapper();
static void Main(string[] args)
{
var objectState = new object();
test.BeginMethod("parameter 1", "parameter 2", Callback, objectState);
Console.ReadKey();
}
private static void Callback(IAsyncResult ar)
{
string result = test.EndMethod(ar);
Console.WriteLine(result);
}
}
public interface ITest
{
IAsyncResult BeginMethod(string s1, string s2, AsyncCallback cb, object state);
string EndMethod(IAsyncResult result);
}
public class Wrapper
{
private ITest proxy = new Test();
public void BeginMethod(string s1, string s2, AsyncCallback cb)
{
proxy.BeginMethod(s1, s2, cb, proxy);
}
public string EndMethod(IAsyncResult result)
{
return ((ITest)(result.AsyncState)).EndMethod(result);
}
}
public class Test : ITest
{
Func<string, string, string> _delgateObject;
private string WorkerFunction(string a, string b)
{
// "long running work"
return a + "|" + b;
}
public IAsyncResult BeginMethod(string s1, string s2, AsyncCallback cb, object state)
{
Func<string, string, string> function = new Func<string, string, string>(WorkerFunction);
this._delgateObject = function;
IAsyncResult result = function.BeginInvoke(s1, s2, cb, state);
return result;
}
public string EndMethod(IAsyncResult result)
{
var test = result.AsyncState;
return this._delgateObject.EndInvoke(result);
}
}
public delegate TResult Func<T1, T2, TResult>(T1 t1, T2 t2);
}

This article helped me understand what was going on. Wcf's OperationContract implements a special Async pattern, that synchronously calls [Operation] on a seperate thread. Begin[Operation] and End[Operation] are used to create the pattern but they will not really be invoked. So this pattern with its signatures and attributes seems to be identical with makeing a synchronous call on the client via e.g. a BackgroundWorker.
You can only set AsyncPattern [of OperationContract attribute] to true on a method with a BeginOperation-compatible signature, and the defining contract must also have a matching method with an EndOperation-compatible signature. These requirements are verified at the proxy load time. What AsyncPattern does is bind the underlying synchronous method with the Begin/End pair, and correlates the synchronous execution with the asynchronous one. Briefly, when the client invokes a method of the form BeginOperation with AsyncPattern set to true, it tells WCF not to try to directly invoke a method by that name on the service. Instead, it will use a thread from the thread pool to synchronously call the underlying method (identified by the Action name). The synchronous call will block the thread from the thread pool, not the calling client. The client will only be blocked for the slightest moment it takes to dispatch the call request to the thread pool. The reply method of the synchronous invocation is correlated with the EndOperation method.

Related

c# calling endinvoke in callback, using generics

Inisde the callback after BeginInvoke, AsyncResult.AsyncDelegate needs to be cast to proper type, only then EndInvoke is accessible.
But I am using generics, so do I need to define N callbacks for N generalized methods?
This is the class:
public class Async
{
public delegate object Func(); //void with no parameter
public delegate TResult Func<T, TResult>(T arg); //one parameter with result
public static void Execute(IAsyncSubscriber subscriber, Func action)
{
action.BeginInvoke(Callback, subscriber);
}
public static void Execute<T, T1>(IAsyncSubscriber subscriber, T param, Func<T, T1> action)
{
action.BeginInvoke(param, Callback, subscriber);
}
private static void Callback(IAsyncResult ar)
{
AsyncResult result = (AsyncResult)ar;
IAsyncSubscriber subscriber = (IAsyncSubscriber)result.AsyncState;
Func action = (Func) result.AsyncDelegate;
object returnValue = action.EndInvoke(result); //To call endinvoke
subscriber.Callback(returnValue);
}
}
There are a few ways in which you can avoid defining N callbacks:
You can pass the corresponding EndInvoke method as state in the BeginInvoke call. e.g.
private delegate T EndInvokeDelegate<T>(IAsyncResult ar);
public static void Execute<T, T1>(IAsyncSubscriber subscriber, T param, Func<T, T1> action)
{
action.BeginInvoke(param, Callback<T1>, new object[]{subscriber, new new EndInvokeDelegate<T1>(action.EndInvoke)});
}
public static void Execute<T, T1, T2>(IAsyncSubscriber subscriber, T param1, T1 param2, Func<T, T1, T2> action)
{
action.BeginInvoke(param1, param2, Callback<T2>, new object[]{subscriber, new new EndInvokeDelegate<T2>(action.EndInvoke)});
}
private static void Callback<TR>(IAsyncResult ar)
{
object[] stateArr = (object[])ar.AsyncState;
IAsyncSubscriber subscriber = (IAsyncSubscriber)stateArr[0];
EndInvokeDelegate<TR> action = (EndInvokeDelegate<TR>)stateArray[1];
TR returnValue = action(ar);
subscriber.Callback(returnValue);
}
You can also make Callback non-generic by treating stateArray[1] as MultiCastDelegate and using DynamicInvoke on it but that would be slow.
For .Net 2.0 and 3.0, you can use reflection e.g.
Type actionType= result.AsyncDelegate.GetType();
var minfo = actionType.GetMethod("EndInvoke");
object returnValue = minfo.Invoke(res.AsyncDelegate, new object[] { ar });
For .Net 4.0, you can use dynamic. e.g.
dynamic action = result.AsyncDelegate;
object returnValue = action.EndInvoke(result);
If I understand correctly, your assumption is correct. You will need to define N callbacks.
On the bright side, you will only be doing this once, so no biggy, just a little repetitive work :)

Using System.Func anonymous and the return object with callback function

Maybe simple question but how can I get the return object of a asynchronously System.Func?
Consider this:
private void Start(String a)
{
System.Func<String, objectA> callasync = delegate(String strA)
{
return bla(stra); // Which return a objectA
}
callasync.BeginInvoke(a, callback, null);
}
private void callback(IAsyncResult ar)
{
// Here I want the objectA but how ??
}
With callback function, I didn't have the delegate signature. And of course, i can create a delegate in scope of the class but maybe is there a solution to read the return value in the callback function.
Thank.
When you use BeginInvoke on a delegate, the IAsyncResult of passed to the callback will be an instance of the AsyncResult class. From that you can get an instance of your delegate and call EndInvoke on it.
private void Start(string a)
{
Func<string, objectA> d = strA => bla(strA);
d.BeginInvoke(a, Callback, null);
}
private void Callback(IAsyncResult ar)
{
AsyncResult asyncResult = (AsyncResult)ar;
Func<string, objectA> d = (Func<string, objectA>)asyncResult.AsyncDelegate;
objectA result = d.EndInvoke(ar);
}
You could also do something like this (not written in IDE, may contain errors)
private Func<String, objectA> _callDoWorkAsync = DoWork;
private static string DoWork( objectA strA )
{
return bla( strA );
}
private void Start( String a )
{
_callDoWorkAsync.BeginInvoke( a, callback, null );
}
private void callback( IAsyncResult ar )
{
objectA strA = (objectA) _callDoWorkAsync.EndInvoke( ar );
}

How to call a method asynchronously? Do I have to create a class that derives from IAsyncResult?

I'm trying to wrap my head around asynchronous calling of methods.
public IDictionary<string, int> DoSomething(string startsWith)
{
return new Dictionary<string, int>();
}
public IAsyncResult BeginDoSomething(string startsWith, AsyncCallback callback,
object state)
{
return new Func<string, IDictionary<string, int>>(DoSomething)
.BeginInvoke(startsWith, callback, state);
}
public IDictionary<string, int> EndDoSomething(IAsyncResult result)
{
// How to return the IDictionary?!
}
My problem is that I have no idea how to get the IDictionary in the EndDoSomething method. I googled around and saw that some people use the state and callback, while others create their own class that derives from IAsyncResult, return it from Begin and cast to it in End.
Is that really the proper way to do it? Or what would be the proper way?
A little unpleasant looking, but this should do it (not explicitly tested):
public IDictionary<string, int> DoSomething(string startsWith)
{
return new Dictionary<string, int>();
}
public IAsyncResult BeginDoSomething(string startsWith, AsyncCallback callback,
object state)
{
var doSomething = new Func<string, IDictionary<string, int>>(DoSomething);
return doSomething.BeginInvoke(startsWith, callback, new object[] { doSomething, state });
}
public IDictionary<string, int> EndDoSomething(IAsyncResult result)
{
var doSomething = (Func<string, IDictionary<string, int>>)((object[])result.AsyncState)[0];
return doSomething.EndInvoke(result);
}
I think you should be looking at this in terms of invoking a synchronous method asynchronously through a delegate.
http://msdn.microsoft.com/en-us/library/22t547yb(v=VS.71).aspx
you need to create a delegate and call that delegate asynchronously.
public delegate IDictionary<String, Int> MyDelegate(string s);
MyDelegate delObj = new MyDelegate(DoSomething);
string str = "testString";
delObj.BeginInvoke(str, new AsyncCallback(CallbackMethod), null);
and
private void CallbackMethod(IAsyncResult iresult)
{
//logic
AsyncResult iResult = iresult as AsyncResult;
MyDelegate del = iResult.AsyncDelegate as MyDelegate;
IDictionary<string,int> result = del.EndInvoke(iresult);
}
http://www.codeproject.com/KB/cs/AsyncMethodInvocation.aspx
not tested it, you can try it out and let me know
Thanks
There are 2 threads that would be running: (1) MainThread and (2)the worker thread that runs DoSomething. Thread (2) is going to call your callback, so it cannot return anything.
Instead, the callback should retrieve the result and put it in a field.
The main thread can then check the value of that field.
Here's an example:
using System;
using System.Collections.Generic;
using System.Threading;
namespace Commons.CLI.Sandbox
{
class Program
{
static void Main(string[] args)
{
var myMain = new Program();
myMain.Run();
Console.WriteLine("Result: " + myMain.Output["start"] + " on thread: " + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
public IDictionary<string, int> Output { get; set; }
private object _outputLock = new object();
private DoSomethingResultRetriever _methodToCall;
private ManualResetEvent _waiter;
public void Run()
{
_waiter = new ManualResetEvent(false);
_methodToCall = DoSomething;
var asyncResult = BeginDoSomething("start");
// We need to wait for the other thread to run
Console.WriteLine(String.Format("Thread {0} is about to wait.", Thread.CurrentThread.ManagedThreadId));
// Do other things ...
if (asyncResult.IsCompleted) return;
_waiter.WaitOne();
}
private IAsyncResult BeginDoSomething(string startsWith)
{
return _methodToCall.BeginInvoke(startsWith, EndDoSomething, null);
}
private void EndDoSomething(IAsyncResult ar)
{
lock (_outputLock)
{
Output = _methodToCall.EndInvoke(ar);
}
_waiter.Set();
}
private delegate IDictionary<string, int> DoSomethingResultRetriever(string startsWith);
private IDictionary<string, int> DoSomething(string startsWith)
{
Console.WriteLine("DoSomething on thread: " + Thread.CurrentThread.ManagedThreadId);
return new Dictionary<string, int>() { { startsWith, 10 } };
}
}
}
I think the easiest way is to use the Task<TResult> class (added in .NET 4), which inherits from IAsyncResult:
public IDictionary<string, int> DoSomething(string startsWith)
{
return new Dictionary<string, int>();
}
public IAsyncResult BeginDoSomething(string startsWith, AsyncCallback callback,
object state)
{
return Task.Factory.StartNew(_ => { return DoSomething(startsWith); }, state);
}
public IDictionary<string, int> EndDoSomething(IAsyncResult result)
{
var task = (Task<IDictionary<string, int>>)result;
return task.Result;
}
Not only does Task<TResult> implement IAsyncResult, but it also handles marshaling any errors to the caller; they are raised automatically by accessing Task<TResult>.Result.

How can I avoid having to pass around/store a delegate when using BeginInvoke and EndInvoke?

Edit: Moved the actual question to the top.
Update: Found an example by Microsoft, tucked on some more code at the end.
My questions are these:
Is it safe to call multiple BeginInvoke calls on the same delegate instance, or do I have to construct a new delegate instance for each in-flight method call?
If I have to construct new instances for each, is there some way to get hold of the original delegate out of the IAsyncResult value?
Is there some other, better, way to add asynchronous support to my class than using delegates?
More info follows.
I am adding asynchronous support to a class of mine, and thought I'd do it simple.
Take this class:
public class Calculator
{
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
}
I thought I could simply do this:
public class Calculator
{
private delegate Int32 AddDelegate(Int32 a, Int32 b);
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public IAsyncResult BeginAdd(Int32 a, Int32 b,
AsyncCallback callback, Object obj)
{
return new AddDelegate(Add).BeginInvoke(a, b, callback, obj);
}
public Int32 EndAdd(IAsyncResult ar)
{
return new AddDelegate(Add).EndInvoke(ar);
}
}
This doesn't work, as the two methods each construct their own delegate object, and the .EndInvoke call checks to see if the delegate instance i call it on is the same as the one I originally called BeginInvoke on.
The simplest way to handle this would be to just store a reference into a variable, like this:
public class Calculator
{
private delegate Int32 AddDelegate(Int32 a, Int32 b);
private AddDelegate _Add;
public Calculator()
{
_Add = new AddDelegate(Add);
}
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public IAsyncResult BeginAdd(Int32 a, Int32 b,
AsyncCallback callback, Object obj)
{
return _Add.BeginInvoke(a, b, callback, obj);
}
public Int32 EndAdd(IAsyncResult ar)
{
return _Add.EndInvoke(ar);
}
}
Note that I'm fully aware of problems with allowing multiple instance methods on the same class to execute at the same time, with regards to shared state, etc.
Update: I found this example here by Microsoft on Asynchronous Delegates Programming Sample. It shows casting the IAsyncResult reference back to an AsyncResult object, and then I can get the original delegate instance through the AsyncDelegate property.
Is this a safe approach?
In other words, is the following class fine?
public class Calculator
{
private delegate Int32 AddDelegate(Int32 a, Int32 b);
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public IAsyncResult BeginAdd(Int32 a, Int32 b, AsyncCallback callback, Object obj)
{
return new AddDelegate(Add).BeginInvoke(a, b, callback, obj);
}
public Int32 EndAdd(IAsyncResult ar)
{
AddDelegate del = (AddDelegate)((AsyncResult)ar).AsyncDelegate;
return del.EndInvoke(ar);
}
}
Edit: if you just mean the delegate itself - I think you can just do:
public Int32 EndAdd(IAsyncResult ar)
{
var d = (AddDelegate)((AsyncResult)ar).AsyncDelegate;
return d.EndInvoke(ar);
}
You could always capture it into the delegate; something like here: Async without the Pain, which lets you just use an Action callback (or Action<T>).
Other common patterns involve events for the callback, and perhaps ThreadPool.QueueUserWorkItem; a lot simpler than IAsyncResult.
Putting all this together; here's an example where neither the caller nor the code needs to get stressed about IAsyncResult:
using System;
using System.Runtime.Remoting.Messaging;
public class Calculator
{
private delegate Int32 AddDelegate(Int32 a, Int32 b);
public Int32 Add(Int32 a, Int32 b)
{
return a + b;
}
public IAsyncResult BeginAdd(Int32 a, Int32 b,
AsyncCallback callback, Object obj)
{
return new AddDelegate(Add).BeginInvoke(a, b, callback, obj);
}
public Int32 EndAdd(IAsyncResult ar)
{
var d = (AddDelegate)((AsyncResult)ar).AsyncDelegate;
return d.EndInvoke(ar);
}
}
static class Program
{
static void Main()
{
Calculator calc = new Calculator();
int x = 1, y = 2;
Async.Run<int>(
(ac,o)=>calc.BeginAdd(x,y,ac,o),
calc.EndAdd, result =>
{
Console.WriteLine(result());
});
Console.ReadLine();
}
}
static class Async
{
public static void Run<T>(
Func<AsyncCallback, object, IAsyncResult> begin,
Func<IAsyncResult, T> end,
Action<Func<T>> callback)
{
begin(ar =>
{
T result;
try
{
result = end(ar); // ensure end called
callback(() => result);
}
catch (Exception ex)
{
callback(() => { throw ex; });
}
}, null);
}
}
I always store the delegate instance I called it on as part of the AsyncState of a BeginInvoke, that way you can always get it without having to rely on a specific implementation of IAsyncResult
Once you've got your IAsyncResult:
IAsyncResult ar; // this has your IAsyncResult from BeginInvoke in it
MethodInvoker d = (MethodInvoker)ar.AsyncState;
d.EndInvoke(ar);

How to pass a function as a parameter in C#?

Is it possible to pass a function as a parameter in C#? I can do it using the Func or Action classes, but this forces me to declare the entire function signature at once. When I try to use Delegate, I get a compile error saying it can't convert a method group to a Delegate.
I'm working on Axial and I'm trying to allow users to call web services. What I'm going for is the ability to create the Visual Studio proxy class and then pass in the generated function. The function signature doesn't matter because the generated code only uses the function name. However, I'd like to pass in the function instead of the name for two reasons: the ability to use the proxy's Url property and a compiler error if the web service doesn't exist or is updated in Visual Studio.
public void AlertIt(object o) {
Axial.DOM.Window.Alert(o.ToString());
}
public void CallAddService() {
object[] param = new object[] { int.Parse(txtA.Text), int.Parse(txtB.Text) };
Axial.ServerScript.CallWebService(new WSProxy.WS().Add, param, AlertIt, AlertIt);
}
class Axial.ServerScript {
public void CallWebService(Delegate method, object[] param, Action<object> successCallback, Action<object> failureCallback) {
// translate to javascript (already working)
}
}
I think what you want is:
static object InvokeMethod(Delegate method, params object[] args){
return method.DynamicInvoke(args);
}
static int Add(int a, int b){
return a + b;
}
static void Test(){
Console.WriteLine(InvokeMethod(new Func<int, int, int>(Add), 5, 4));
}
Prints "9".
Converting a method group, anonymous method or lambda expression to a delegate requires the compiler to know the exact delegate type. However, you could potentially use lambda expressions and captured variables to make this simpler:
public void InvokeMethod(Action action)
{
action();
}
public int Add(int a, int b)
{
return a + b;
}
public void Test()
{
InvokeMethod(() => Add(2, 3));
}
That basically delays invocation in the normal way, but by wrapping the actual call to Add in a plain Action delegate.
If that doesn't fulfil your requirements, perhaps you can tell us a bit more about what you're really trying to achieve.
EDIT: If this is generated code, you can cast to a Func<...> with the right type arguments - assuming there aren't too many. Other than that, there's no real way of just passing in a method group. There's been occasional calls for an "infoof(...)" operator (like typeof but for members) which would give you a MemberInfo, but that doesn't actually exist.
You should have a delegate first
delegate int Operation(int a, int b)
then it becomes:
public void InvokeMethod(Operation method, object target, object param)
{
method((int) target, (int) param);
}
No need for any call to Invoke.
As with dbone I'm unsure why you would need a params[] array. Would you clarify the expanded usage for the params?
Also, I'll have to correct something in your question though, because it will cause a compilation error :p
please have a look at using delegates here is a great example
Delegate Example
why are you using reflection? will there ever be a different number of params? or do you know the method signture will remain constant (also remember C# supports the params[] keyword)
params c#
HTH
Bones
Look at Functional Programming Series by Justin Etheredge.
You should find solution to your problem there.
This is much simple example, to programmer who already familiar with (C/C++/VB.NET/Python)-style pass function by pointer/ref (with C# delegate):
delegate void CALLBACK(String s);
static void Main(string[] args)
{
Get("some string", testfunc);
Util.pause();
}
static void Get(String s, CALLBACK x)
{
x(s);
}
static void testfunc(String s)
{
Console.WriteLine(s);
}
Say If you need to pass the method as parameter as well as you need to catch the return value for further processing . Then the above examples will work fine .
But say if you need to pass a method with void return type then you need to create one more version of the InvokeMethod function.
Check the example below.
private static T retry<T>(Delegate method, params object[] args)
{
for (int i = 0; i <= 3; i++)
{
try
{
return (T)method.DynamicInvoke(args);
}
catch (Exception ex)
{
if (i == 3)
{
logMessage(ex.Message);
}
Console.WriteLine("Retry count " + i);
Thread.Sleep(10);
}
}
return default(T);
}
private static void retry2(Delegate method, params object[] args)
{
for (int i = 0; i <= 3; i++)
{
try
{
method.DynamicInvoke(args);
break;
}
catch (Exception ex)
{
if (i == 3)
{
logMessage(ex.Message);
//return default(T);
}
Console.WriteLine("Retry count " + i);
Thread.Sleep(10);
}
}
}
static bool isSuccess = true;
static void logMessage(string msg)
{
isSuccess = false;
Console.WriteLine(msg);
}
static int Add(int a, int b)
{
return a + b;
}
static void Add2(int a, int b)
{
int c = a + b;
Console.WriteLine(c);
}
static void Main(string[] args)
{
int d = retry<int>(new Func<int, int, int>(Add), 6, 7.7);
Console.Write(" " + d + "\n"+isSuccess);
retry2(new Action<int, int>(Add2), 45, 60);
Console.ReadKey();
}
Something like this ought to work for you:
delegate int MyDelegate(int a, int b);
public int Add(int a, int b) {
return a + b;
}
public void InvokeMethod(Delegate method, object[] param) {
Console.WriteLine(method.DynamicInvoke(param));
}
public Form1() {
InitializeComponent();
InvokeMethod(new MyDelegate(Add), new object[] { 1, 2 });
}
Good luck!

Categories