Class Client{
main(){
MyRequest m = new MyRequest();
m.function();
}
onSucess(string s){
Debug.log("i get data from network:"+s);
}
}
Class Network{
sendMyrequest(MyRequest r){
Thread thread = new Thread(() => sendMyrequestTask(r));
thread.start();
}
private void sendMyrequestTask(MyRequest r){
if(...){
//call delegate function onSucess(string s)
}
}
}
Class MyRequest{
private Network network;
function(){
//do something
network.sendMyrequest(MyRequest r);
}
}
in this case, callback function onSucess(string s) should be a delegate, or a interface, how and where should I implement it? Any suggestion would be appreciate. Thanks in advance!!
Edit: this problem is like: A call B,B call C, when C's job is done, C should call A. How to implement this?
Thanks all guys. I implement in this way.
public interface CallbackFunction{
public onSucess(string s);
}
Class Client:CallbackFunction{
main(){
MyRequest m = new MyRequest();
m.function(this);
}
onSucess(string s){
Debug.log("i get data from network:"+s);
}
}
Class Network{
sendMyrequest(MyRequest r,CallbackFunction c){
Thread thread = new Thread(() => sendMyrequestTask(r,c));
thread.start();
}
private void sendMyrequestTask(MyRequest r,CallbackFunction c){
if(...){
//call delegate function onSucess(string s)
c.onSucess("bla bla bla");
}
}
}
Class MyRequest{
private Network network;
function(CallbackFunction c){
//do something
network.sendMyrequest(this,c);
}
}
You can use async and `await.
For more info :
Many methods do not immediately return. A method may need to query an external source. This takes time. With async and await, we formalize and clarify how asynchronous, non-blocking methods begin and end.
http://msdn.microsoft.com/en-us/library/hh191443.aspx
http://msdn.microsoft.com/en-us/library/hh156513.aspx
By using the Action<> delegate as a constructor argument in MyRequest we can achieve something like this.
You can replace the Action<> type with any other delegate you might want to use. Action<> or Func<> should cover just about anything.
By the way, your code, and hence my code below is not the observer pattern.
public class Client
{
static void Main(string[] args)
{
var client = new MyRequest(OnSuccess);
client.Function();
//Output:
//I'm in the callback
//Foo.Bar()
Console.ReadKey();
}
static void OnSuccess(string result)
{
Console.WriteLine("I'm in the callback");
Console.WriteLine(result);
}
}
public class Network
{
public void SendMyRequest(MyRequest request)
{
var result = "Foo.Bar()";
if (!String.IsNullOrEmpty(result))
{
request.SuccessCallback(result);
}
}
}
public class MyRequest
{
public Action<string> SuccessCallback { get; private set; }
private Network _network;
public MyRequest(Action<string> successCallback)
{
_network = new Network();
SuccessCallback = successCallback;
}
public void Function()
{
_network.SendMyRequest(this);
}
}
It looks like you want to implement something similar to WebClient.DownloadStringCompleted event. Which uses following delegate type:
public delegate void DownloadStringCompletedEventHandler(
Object sender
DownloadStringCompletedEventArgs e)`
with following usage pattern:
WebClient client = new WebClient ();
client.DownloadStringCompleted += DownloadStringCallback2;
client.DownloadStringAsync (new Uri(address));
Note: if you don't expect multiple listeners using async/await will lead to much easier to understand code.
Related
I have a func delegate that is defined as follows,
public enum RunEndStatus
{
Success
}
public class classA
{
Func<object, RunEndStatus> ProcessCalibrationRun { get; set; }
}
Now in an other class lets say classB I am doing something like this,
public class ClassB
{
public void DoSomething()
{
ClassA a = new ClassA();
a.ProcessCalibrationRun = ProcessCalibrationRun;//This is just fine. It won't complain here.
}
public RunEndStatus ProcessCalibrationRun(object obj)
{
//Here I have some piece of code takes so much time. To replicate it,
Thread.Sleep(10000);
}
}
When the DoSomething method is called from somewhere, the application blocks for 10 minutes.So I am trying to fix my problem as follows,
public async Task<RunEndStatus> ProcessCalibrationRun(object obj)
{
await Task.Run(() => { Thread.Sleep(10000)});
return RunEndStatus.Success;
}
I am modifying the call as follows. But it says cannot await method group. Please help how can I await on that method.
public async void DoSomething()
{
ClassA a = new ClassA();
a.ProcessCalibrationRun = await ProcessCalibrationRun; //Here it complains saying cannot await method group.
}
An async signature returns a Task, so your Func will need to as well
public Func<object, Task<RunEndStatus>> ProcessCalibrationRun { get; set; }
Meaning you will not need the async signature in your DoSomething, which should not be async void anyway
public void DoSomething()
{
vara = new ClassA();
a.ProcessCalibrationRun = ProcessCalibrationRun;
}
Then somewhere else (perhaps in ClassA) you can invoke it
public async Task DoSomethingElse()
{
await ProcessCalibrationRun(somethignObject);
}
This is a confusing matter for me, hope to describe it correctly.
This is in a Xamarin.Android project:
I have a class like this (simplified):
public class FinishedListener : Java.Lang.Object, IabHelper.IOnIabSetupFinishedListener
{
public IabResult Data { get; internal set; } = null;
public void OnIabSetupFinished(IabResult res)
{
if (res != null) { Data = res; }
}
}
and a calling method:
public class Class1
{
public void Method1()
{
FinishedListener listner = new FinishedListener();
SomeClass.Init(listner );
// Do something with "listner.Data.Response"
}
}
Because Init class works asynchronously, listner.Data will not be available at once.
What's the best way to implement waiting for this scenario?
I am not sure if your Init method is awaitable, assuming it is you can do something like this;
public async void Method1()
{
FinishedListener listner = new FinishedListener();
await SomeClass.Init(listner);
// Do something with "listner.Data.Response"
}
In case it is non-awaitable do this:
public async void Method1()
{
FinishedListener listner = new FinishedListener();
await Task.Run(()=>{ SomeClass.Init(listner); });
// Do something with "listner.Data.Response"
}
When this executes what will happen is that your existing compiler will wait for execution of await SomeClass.Init(listner); and then the next line shall execute.
I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}
I am creating a C# library with some reusable code and was trying to create a method inside a method. I have a method like this:
public static void Method1()
{
// Code
}
What I would like to do is this:
public static void Method1()
{
public static void Method2()
{
}
public static void Method3()
{
}
}
Then I could choose either Method1.Method2 or Method1.Method3. Obviously the compiler isn't happy about this, any help is much appreciated. Thanks.
If by nested method, you mean a method that is only callable within that method (like in Delphi) you could use delegates.
public static void Method1()
{
var method2 = new Action(() => { /* action body */ } );
var method3 = new Action(() => { /* action body */ } );
//call them like normal methods
method2();
method3();
//if you want an argument
var actionWithArgument = new Action<int>(i => { Console.WriteLine(i); });
actionWithArgument(5);
//if you want to return something
var function = new Func<int, int>(i => { return i++; });
int test = function(6);
}
Yes, when C# 7.0 is released, Local Functions will allow you to do that. You will be able to have a method, inside a method as:
public int GetName(int userId)
{
int GetFamilyName(int id)
{
return User.FamilyName;
}
string firstName = User.FirstName;
var fullName = firstName + GetFamilyName(userId);
return fullName;
}
Note that public (and similar modifiers) are not supported C# programming guide:
Because all local functions are private, including an access modifier, such as the private keyword, generates compiler error CS0106, "
This answer was written before C# 7 came out. With C# 7 you can write local methods.
No, you can't do that. You could create a nested class:
public class ContainingClass
{
public static class NestedClass
{
public static void Method2()
{
}
public static void Method3()
{
}
}
}
You'd then call:
ContainingClass.NestedClass.Method2();
or
ContainingClass.NestedClass.Method3();
I wouldn't recommend this though. Usually it's a bad idea to have public nested types.
Can you tell us more about what you're trying to achieve? There may well be a better approach.
You can define delegates within your method with complete code and call them if you want.
public class MyMethods
{
public void Method1()
{
// defining your methods
Action method1 = new Action( () =>
{
Console.WriteLine("I am method 1");
Thread.Sleep(100);
var b = 3.14;
Console.WriteLine(b);
}
);
Action<int> method2 = new Action<int>( a =>
{
Console.WriteLine("I am method 2");
Console.WriteLine(a);
}
);
Func<int, bool> method3 = new Func<int, bool>( a =>
{
Console.WriteLine("I am a function");
return a > 10;
}
);
// calling your methods
method1.Invoke();
method2.Invoke(10);
method3.Invoke(5);
}
}
There is always an alternative of using a nested class within a class that will not be visible from outside and calling its methods, like:
public class SuperClass
{
internal static class HelperClass
{
internal static void Method2() {}
}
public void Method1 ()
{
HelperClass.Method2();
}
}
As of C# 7.0 you can do that:
public static void SlimShady()
{
void Hi([CallerMemberName] string name = null)
{
Console.WriteLine($"Hi! My name is {name}");
}
Hi();
}
This is called local functions, that is just what you were looking for.
I took the example from here, but further informatin can be found here and here.
Why you don't use classes?
public static class Helper
{
public static string MethodA()
{
return "A";
}
public static string MethodA()
{
return "A";
}
}
Now you can acces MethodA via
Helper.MethodA();
Older thread, but C# does have the concept of nested functions
Func<int> getCalcFunction(int total, bool useAddition)
{
int overallValue = 0;
if (useAddition)
{
Func<int> incrementer = new Func<int>(() =>
{
overallValue += total;
return overallValue;
});
return incrementer;
}
else
{
Func<int> decrementer = new Func<int>(() =>
{
overallValue -= total;
return overallValue;
});
return decrementer;
}
}
private void CalcTotals()
{
Func<int> decrem = getCalcFunction(30, false);
int a = decrem(); //result = -30
a = decrem(); //result = -60
Func<int> increm = getCalcFunction(30, true);
int b = increm(); //result = 30
b = increm(); //result = 60
}
Your nearly there
public static void Method1()
should be
public static class Method1{}
Don't you want to use nested class instead?
That's said, you seem to not respect the Single Responsibility Principle because you want a single method do more than one thing at a time.
Why don't you just Run a method within another
public void M1()
{
DO STUFF
}
public void M1()
{
DO STUFF
M1();
}
I'm working on a little technical framework for CF.NET and my question is, how should I code the asynchronous part? Read many things on MSDN but isn't clear for me.
So, here is the code :
public class A
{
public IAsyncResult BeginExecute(AsyncCallback callback)
{
// What should I put here ?
}
public void EndExecute()
{
// What should I put here ?
}
public void Execute()
{
Thread.Sleep(1000 * 10);
}
}
If someone can help me...
Thanks !
You could use a delegate:
public class A
{
public void Execute()
{
Thread.Sleep(1000 * 3);
}
}
class Program
{
static void Main()
{
var a = new A();
Action del = (() => a.Execute());
var result = del.BeginInvoke(state =>
{
((Action)state.AsyncState).EndInvoke(state);
Console.WriteLine("finished");
}, del);
Console.ReadLine();
}
}
UPDATE:
As requested in the comments section here's a sample implementation:
public class A
{
private Action _delegate;
private AutoResetEvent _asyncActiveEvent;
public IAsyncResult BeginExecute(AsyncCallback callback, object state)
{
_delegate = () => Execute();
if (_asyncActiveEvent == null)
{
bool flag = false;
try
{
Monitor.Enter(this, ref flag);
if (_asyncActiveEvent == null)
{
_asyncActiveEvent = new AutoResetEvent(true);
}
}
finally
{
if (flag)
{
Monitor.Exit(this);
}
}
}
_asyncActiveEvent.WaitOne();
return _delegate.BeginInvoke(callback, state);
}
public void EndExecute(IAsyncResult result)
{
try
{
_delegate.EndInvoke(result);
}
finally
{
_delegate = null;
_asyncActiveEvent.Set();
}
}
private void Execute()
{
Thread.Sleep(1000 * 3);
}
}
class Program
{
static void Main()
{
A a = new A();
a.BeginExecute(state =>
{
Console.WriteLine("finished");
((A)state.AsyncState).EndExecute(state);
}, a);
Console.ReadLine();
}
}
You don't need to do anything special, cause the caller should call you method async,
He define a new delegate pointing to you method, and use the .net to call your method asynchronously.
On BeginExecute you have to start the asynchronous operation (possibly start execute in a separate thread) and return as quick as possible. Execute has to call the AsyncCallback at the end of all operations so that who use the async operation gets aware and get the result. EndExecute has to stop a previously started async operation (possibly interrupting the thread launched by BeginExecute).
Without more details this is the best I can do.
If you want to run piece of code asynchronously, you should use BackgroundWorker. Unless of course, the code you are calling doesn't support asynchronous operation natively. Just like Read/Write methods or service calls.
If you want to notify, that the asynchronous operation has finished, use delegate or event callback.