I am creating a Windows forms application which executes a lot of similar operations on a piece of data. All these operations are almost the same so I would like to create a single method that
makes the user interface read-only
sets up messages like "Executing operation1..."
executes the operation asynchronously, so the user interface remains responsive
sets up message to "Operation1 finished."
Set interface read-only to false.
I imagine calling this single method like
ExecuteOperation([method to execute], "Executing operation1")
I am sure that this is simple but I am lost between delegates and tasks so please show me how to write a method that is capable of running a selected method, preferably with multiple parameters and how this method is called.
Note:
By disabling the interface I mean
MainMenu.Enabled = false;
txtData.ReadOnly = true;
You're probably looking for something like this (I've shown an example here for a method that takes parameters, since you asked for that case specifically):
private async Task ExecuteOperation(string operationName, Action action)
{
//Disable UI here
//Set 'Executing' message here
await Task.Run(action);
//Set 'Finished' message here
//Enable UI here
}
private async Task CallOperation()
{
int x, y, z; //These get set to something here...
await ExecuteOperation("Operation1", () => OperationWithParams(x, y, z));
}
You most likely also want to add some exception handling in your ExecuteOperation wrapper if you have standard exceptions that your various operations can throw and which should result in UI feedback of some sort.
On a side note, I reordered the name and the action, as this makes it somewhat cleaner (IMO) to pass an anonymous method as the action.
You can pass methods into methods, so to speak, but the delegates have to match. If you have methods with different signatures, you're angling the wrong way.
The Action and Func delegates are generic. There's one to match almost any signature (up to 16 parameters), but again, they have to match the method signature. If you have one method with one parameter, and another with two, or two with different types of parameters, you can't pass those into the same delegate.
So, really it depends on how similar your methods are. If they have varied types of parameters, you'd probably have to "wrap" these calls.
Simplified example:
void Main()
{
List<Action> actions = new List<Action>
{
() => Method1("myString"),
() => Method2("myString2", "myString3")
};
foreach(var action in actions) InvokeAction(action);
}
void InvokeAction(Action action)
{
action();
}
void Method1(string x)
{
Console.WriteLine(x);
}
void Method2(string y, string z)
{
Console.WriteLine(y);
Console.WriteLine(z);
}
On the other hand, if your methods have the same signature, it's a bit simpler:
void Main()
{
InvokeAction(Method1, "myString");
InvokeAction(Method2, "myString2");
}
void InvokeAction(Action<string> action, string param)
{
action(param);
}
void Method1(string x)
{
Console.WriteLine(x);
}
void Method2(string y)
{
Console.WriteLine(y);
}
Now, as to running that asynchronously, it's as simple as using a System.Threading.Task, if you're on .NET 4.0. You could alter my example method as such:
void InvokeAction(Action<string> action, string param)
{
Task.Factory.StartNew(() => action(param));
}
How about something like this (non async/await - version):
void Foo<T>(Action<T> action, string message)
{
MethodWhichMakesMyInterfaceReadOnlyAndSetsMessage(message);
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (obj, arg) => action.Invoke();
worker.RunWorkerCompleted +=
(obj, arg) =>
{
MethodWhichMakesMyInterfaceReadWrite();
};
worker.RunWorkerAsync();
}
I wrote this before I realised you wanted async/await and tasks specifically - someone else has answered with that however. You can create whatever overloads you want for the extra params for your action.
Related
Is there a way I can pass through an argument to an Action without using an anonymous function?
Eg, the following code works fine:
private void doSomethingAndLogIt(string log, Action dosomething)
{
Debug.WriteLine(log);
dosomething();
}
private void multiplyIt()
{
_result = "great";
}
...
doSomethingAndLogIt("Did something", multiplyIt);
but what I want to do is this:
private void doSomethingAndLogIt(string log, Action<int> dosomething)
{
Debug.WriteLine(log);
dosomething(???);
}
private void multiplyIt(int a)
{
_result = "great";
}
doSomethingAndLogIt("Did something", multiplyIt(5));
I realise that I can do this:
private void doSomethingAndLogIt(string log, Action<int> dosomething, int inputValue)
{
Debug.WriteLine(log);
dosomething(inputValue);
}
private void multiplyIt(int a)
{
_result = "great";
}
doSomethingAndLogIt("Did something", multiplyIt, 5);
but it's pretty confusing. I also realise that I can do this:
doSomethingAndLogIt("Did something", () => {
multiplyIt(5);
});
but it would be great if I could do this:
doSomethingAndLogIt("Did something", multiplyIt(5));
You do not need to do anything special. This code below:
doSomethingAndLogIt("Test", () => multiplyIt(5));
will already do what you are after. When the delegate is called, the parameter 5 will be passed in as well. Why? Because the callee will call your delegate, and you will call the method multiply with the argument 5.
Here is a quick test.
It isn't possible to do that as of the current version of C#, here's why...
Let's take your example (fake syntax)
public int MultiplyIt(int value)
{
//Do something that has side-effects
}
public void SomeMethod(Action<int> someAction<int>)
{
//Do something
someAction();
}
Now let's create an override of that method:
public void SomeMethod(int someValue)
{
//Do something
}
Now you call it:
SomeMethod(multiplyIt(5))
Which one does the compiler call?
Lets say you don't overload it (or that for some reason the compiler shouts an error if you do, but it is legal).
What then is the difference between these two calls?
SomeMethod(multiplyIt(5));
SomeMethod(() => multiplyIt(5));
Technically the first one runs multiplyIt before passing its value to SomeMethod. The second one multiplyIt may never be called, or it may alter something and then call it. That is an important distinction. If you add in some method to call it without the () => part, the developer can't know, without reading documentation, how the method call (and the action) are called. Is it a normal method call? The "special" delegate case? Who knows.
The () => isn't that much of a price to pay to be able to read a method and understand that you are passing in a delegate vs a value.
I have a method that I call multiple times, but each time a different method with a different signature is called from inside.
public void MethodOne()
{
//some stuff
*MethodCall();
//some stuff
}
So MethodOne is called multiple times, each time with a different *MethodCall(). What I'm trying to do is something like this :
public void MethodOne(Func<> MethodCall)
{
//some stuff
*MethodCall;
//some stuff
}
but the Methods that are called each have a different return type and different parameters. Is there a way to do this using Functors? If not, how would I go about doing this?
Thank you!
You best bet would be to use the non-generic Action type (or MethodInvoker would be the same), i.e.
public void MethodOne(Action callback)
{
//some stuff
if(callback != null) callback();
//some stuff
}
From this you can call any method by wrapping it at the caller, i.e.
MethodOne(SimpleMethod); // SimpleMethod has no parameters and returns void
MethodOne(() => MoreComplexMethod(1, "abc")); // this one returns void
MethodOne(() => { MethodThatReturnsSomething(12); }); // anything you like
etc
You cannot call a function which requires parameters without supplying them, so the answer is "no, not possible"
Also, maybe you want the following:
void MethodOne(Action a)
{
// some stuff
a();
// some stuff
}
... // somewhere in the code
MethodOne((Action)(() => { DoSomethingOther(1, 2, 3); }));
MethodOne((Action)(() => { DoSomethingEvenDifferent(1, 2, 3, 4, 5); }));
Every delegate in .Net is an instance of a class derived from Delegate. So if you really wish to pass 'any' delegate to a method, you can pass it as Delegate
To invoke it, you need to use its DynamicInvoke method.
public void MethodOne(Delegate MethodCall)
{
//some stuff
//Assuming you now have the required parameters
//or add params object[] args to the signature of this method
object res = MethodCall.DynamicInvoke(args); //args is object[] representing the parameters
//some stuff
}
But this is not recommended as DynamicInvoke is slow and it does not offer any compile time safety. Probably you should revisit your design.
This is basically not possible. You could make MethodOne generic for the return type, and use a lambda that closes over its outside block instead of parameters:
static void Main(string[] args)
{
int parameterSubst = 1;
int result = MethodOne<int>(() => parameterSubst);
string result2 = MethodOne<string>(() =>
{
string s = parameterSubst.ToString();
s += "foo";
return s;
});
}
static T MethodOne<T>(Func<T> function)
{
return function();
}
As you can see, parameterSubst is used in the passed Func<T>s, but not as a parameter.
So I'm a little bit confused about delegates in C#.... what do they do and how are they useful? I've read a few tutorials, and I don't really get exactly what they're supposed to do (everyone relates them to function pointers in C, and I've never programmed in C).
So... what do delegates do? What's a scenario in which I should use them? How would I then use them?
The other answers are good, but here's another way to think about delegates that might help. Imagine that a delegate is nothing more than an interface. When you see:
delegate void Action();
think:
interface IAction
{
void Invoke();
}
And when you see:
Action myAction = foo.Bar;
think:
class FooBarAction : IAction
{
public Foo Receiver { get; private set; }
public FooBarAction(Foo foo)
{
this.Receiver = foo;
}
public void Invoke()
{
this.Receiver.Bar();
}
}
...
IAction myAction = new FooBarAction(foo);
And when you see
myAction();
think
myAction.Invoke();
The actual details of what types get constructed are a bit different, but fundamentally that's what's happening. A delegate is simply an object with a method called Invoke, and when you call that method, it calls some other method on some other object on your behalf. That's why it's called a "delegate" -- because it delegates the call to another method of another object.
Delegates are sort of like objects that represent a method call. One useful way they can be used are as callbacks. For example, imagine you have a method that does something asynchronous, and you want the caller to be able to specify what they want to happen once it completes (Action is a type of delegate):
public void DoSomething(Action whatToDoWhenDone)
{
// Your code
// See how the delegate is called like a method
whatToDoWhenDone();
}
A user of DoSomething can now specify the callback as a parameter:
public void AnotherMethod()
{
DoSomething(ShowSuccess); // ShowSuccess will be called when done
}
public void ShowSuccess()
{
Console.WriteLine("Success!");
}
You can also use lamba expressions as a shorter way of writing your delegate:
public void AnotherMethod()
{
DoSomething(() => Console.WriteLine("Success!"));
// Also DoSomething(delegate() { Console.WriteLine("Success!"); });
}
Callbacks are far from the only use cases for delegates. Hopefully this shows you some of their power: the ability to have code to be executed as a variable.
Delegates allow you to treat functions as if they were any other variable. A delegate type defines the signature of the function, that is, what the function returns, and the number and type of arguments that it takes:
// This is the delegate for a function that takes a string and returns a string.
// It can also be written using the framework-provided Generic delegate Func, as
// Func<String, String>
delegate String StringToStringDelegate(String input);
You can define a variable of this type, and assign it to an existing method. I use the generic as an example, because that is the more common usage in .net since 2.0:
String Reverse(String input) {
return input.Reverse();
}
Func<String, String> someStringMethod = new Func<String, String>(Reverse);
// Prints "cba":
Console.WriteLine(someStringMethod("abc"));
You can also pass functions around this way:
String Reverse(String input) {
return input.Reverse();
}
String UpperCase(String input) {
return input.ToUpper();
}
String DoSomethingToABC(Func<String, String> inputFunction) {
return inputFunction("abc");
}
var someStringMethod = new Func<String, String>(Reverse);
// Prints "cba":
Console.WriteLine(DoSomethingToABC(someStringMethod));
var someOtherStringMethod = new Func<String, String>(UpperCase);
// Prints "ABC":
Console.WriteLine(DoSomethingToABC(someOtherStringMethod));
In a big application it is often required to other parts of the application based on some condition or something else. The delegate specifies the address of the method to be called. In simple manner a normal event handler implements the delegates in the inner layers.
The oversimplified answer is that a delegate is basically a "pointer" to a block of code, and the benefit is that you can pass this block of code into other functions by assigning your block of code to a variable.
The reason people relate Delegates to C function pointers is because this is in essence what delegation is all about, I.e.: Pointers to methods.
As an example:
public void DoSomething(Action yourCodeBlock)
{
yourCodeBlock();
}
public void CallingMethod()
{
this.DoSomething(
{
... statements
});
this.DoSomething(
{
... other statements
});
}
There are naturally lots of ways to invoke delegates as all of the tutorials will show you. The point is though that it allows you to "delegate" functionality in such a way that you can call into methods without necessarily knowing how they work, but simply trusting that they will be taken care of. In other words, I might create a class that implements a "DoSomething()" function, but I can leave it up to someone else to decide what DoSomething() will do later on.
I hope that helps. :-)
Delegates are a way to call back into your code when a long running operation completes or when an event occurs. For example, you pass a delegate to a method that asynchronously downloads a file in the background. When the download is complete, your delegate method would be invoked and it could then take some action such as processing the file's contents.
An event handler is a special type of delegate. For example, an event handler delegate can respond to an event like a mouse click or key press. Events are by far the most common type of delegate. In fact, you will typically see the event keyword used far more often in C# code than the delegate keyword.
You can think of it as a type in which you may store references to functions. That way you can in effect, store a function in a variable so you may call it later like any other function.
e.g.,
public delegate void AnEmptyVoidFunction();
This creates a delegate type called AnEmptyVoidFunction and it may be used to store references to functions that return void and has no arguments.
You could then store a reference to a function with that signature.
public static void SomeMethod() { }
public static int ADifferentMethod(int someArg) { return someArg; }
AnEmptyVoidFunction func1 = new AnEmptyVoidFunction(SomeMethod);
// or leave out the constructor call to let the compiler figure it out
AnEmptyVoidFunction func2 = SomeMethod;
// note that the above only works if it is a function defined
// within a class, it doesn't work with other delegates
//AnEmptyVoidFunction func3 = new AnEmptyVoidFunction(ADifferentMethod);
// error wrong function type
Not only can it store declared functions but also anonymous functions (i.e., lambdas or anonymous delegates)
// storing a lambda function (C#3 and up)
AnEmptyVoidFunction func4 = () => { };
// storing an anonymous delegate (C#2)
AnEmptyVoidFunction func5 = delegate() { };
To call these delegates, you can just invoke them like any other function call. Though since it is a variable, you may want to check if it is null beforehand.
AnEmptyVoidFunction func1 = () =>
{
Console.WriteLine("Hello World");
};
func1(); // "Hello World"
AnEmptyVoidFunction func2 = null;
func2(); // NullReferenceException
public static void CallIt(AnEmptyDelegate func)
{
// check first if it is not null
if (func != null)
{
func();
}
}
You would use them any time you needed to pass around a method that you wish to invoke. Almost in the same way that you may pass instances of objects so you may do what you wish with them. The typical use case for delegates is when declaring events. I have written another answer describing the pattern so you can look at that for more information on how to write those.
In my project I heavily make use of TPL, and I decide to design a generic way of producing tasks, instead of calling new Task(Action);, new Task(Action<object>, object); or Task.Factory.StartNew(Action) etc. explicitly.
I will have a function like
void SpawnTask<A,B>( Action<A,B> action, A a, B b) { ... }
void SpawnTask<A,B,C>( Action<A,B,C> action, A a, B b, C c) { ... }
for creating and starting tasks.
Also I need to run a mandatory method after each task completed. Thus I have to wrap the actual method I want to run in another method like
void RuncTask(Action action)
{
action();
MandatoryMethod();
}
So far I come up with two different approaches.
First, using anonymous delegates:
void SpawnTask<A,B>(Action<A,B> action, A a, B b)
{
A dummyA = a; // To localize the parameters.
B dummyB = b;
var methodDelegate = delegate { action(dummyA,dummyB); };
var taskDelegate = delegate { RunTask(methodDelegate); };
Task.Factory.StartNew( taskDelegate );
}
void RuncTask(Action action)
{
action();
MandatoryMethod();
}
Second, using tuple:
void SpawnTask<A,B>(Action<A,B> action, A a, B b)
{
Tuple<Action<A,B>, A, B> tpl = Tuple.Create(action, a, b);
Action<object> act = RunTask<A,B>;
Task.Factory.StartNew( act, tpl );
}
void RuncTask<A,B>(object obj)
{
var tpl = (Tuple<Action<A, B>, A, B>)param;
tpl.Item1(tpl.Item2,tpl.Item3);
MandatoryMethod();
}
I like the first one because, it is simpler. The second has casting, requires other generic RunTask methods to be implemented for different number of parameters. But I do not know if creating too much anonymous delegates can cause side effects.
Which one do you prefer? Why? Or what other solutions do you have?
Well, you can always create an extension method on Action<TA,TB> ... and you should use continuations rather than wrapped method calls to implement the behavior of always performing another action when the task completes:
public static class TaskExtensions
{
public static void RunTask<TA,TB>( Action<TA,TB> action, TA a, TB b )
{
Task newTask = new Task( () => action(a,b) );
newTask.ContinueWith( MandatoryMethod );
newTask.Start();
}
// if you need to support other signature (more parameters) you would need to
// create additional overloads of RunTask with more generic parameters...
public static void RunTask( Action action );
public static void RunTask<TA>( Action<TA> action, TA a );
// etc ...
private static void MandatoryMethod( Task t ) { /* your continuation logic */ }
}
Now you can use this code as follows:
public void SomeMethod( int x, int y ) { ... }
// later...
Action<int,int> myAction = SomeMethod;
myAction.RunTask( 1, 2 );
Note that in the above implementation the continuation method (MandatoryMethod) will be executed asynchronously. If you desire synchronous execution (as is implemented in your example), you can use the overload of ContinueWith that takes a TaskContinuationOptions and pass in TaskContinuationOptions.ExecuteSynchronously.
Frankly, I mot quite sure what you are trying to accomplish with that. What advantage over directly using Task constructor or Task.Factory are you hoping to achieve?
As for a "mandatory method" that needs to execute after task finishes, look at continuations (e.g. Task.ContinueWith).
I have simple method in my C# app, it picks file from FTP server and parses it and stores the data in DB. I want it to be asynchronous, so that user perform other operations on App, once parsing is done he has to get message stating "Parsing is done".
I know it can achieved through asynchronous method call but I dont know how to do that can anybody help me please??
You need to use delegates and the BeginInvoke method that they contain to run another method asynchronously. A the end of the method being run by the delegate, you can notify the user. For example:
class MyClass
{
private delegate void SomeFunctionDelegate(int param1, bool param2);
private SomeFunctionDelegate sfd;
public MyClass()
{
sfd = new SomeFunctionDelegate(this.SomeFunction);
}
private void SomeFunction(int param1, bool param2)
{
// Do stuff
// Notify user
}
public void GetData()
{
// Do stuff
sfd.BeginInvoke(34, true, null, null);
}
}
Read up at http://msdn.microsoft.com/en-us/library/2e08f6yc.aspx
try this method
public static void RunAsynchronously(Action method, Action callback) {
ThreadPool.QueueUserWorkItem(_ =>
{
try {
method();
}
catch (ThreadAbortException) { /* dont report on this */ }
catch (Exception ex) {
}
// note: this will not be called if the thread is aborted
if (callback!= null) callback();
});
}
Usage:
RunAsynchronously( () => { picks file from FTP server and parses it},
() => { Console.WriteLine("Parsing is done"); } );
Any time you're doing something asynchronous, you're using a separate thread, either a new thread, or one taken from the thread pool. This means that anything you do asynchronously has to be very careful about interactions with other threads.
One way to do that is to place the code for the async thread (call it thread "A") along with all of its data into another class (call it class "A"). Make sure that thread "A" only accesses data in class "A". If thread "A" only touches class "A", and no other thread touches class "A"'s data, then there's one less problem:
public class MainClass
{
private sealed class AsyncClass
{
private int _counter;
private readonly int _maxCount;
public AsyncClass(int maxCount) { _maxCount = maxCount; }
public void Run()
{
while (_counter++ < _maxCount) { Thread.Sleep(1); }
CompletionTime = DateTime.Now;
}
public DateTime CompletionTime { get; private set; }
}
private AsyncClass _asyncInstance;
public void StartAsync()
{
var asyncDoneTime = DateTime.MinValue;
_asyncInstance = new AsyncClass(10);
Action asyncAction = _asyncInstance.Run;
asyncAction.BeginInvoke(
ar =>
{
asyncAction.EndInvoke(ar);
asyncDoneTime = _asyncInstance.CompletionTime;
}, null);
Console.WriteLine("Async task ended at {0}", asyncDoneTime);
}
}
Notice that the only part of AsyncClass that's touched from the outside is its public interface, and the only part of that which is data is CompletionTime. Note that this is only touched after the asynchronous task is complete. This means that nothing else can interfere with the tasks inner workings, and it can't interfere with anything else.
Here are two links about threading in C#
Threading in C#
Multi-threading in .NET: Introduction and suggestions
I'd start to read about the BackgroundWorker class
In Asp.Net I use a lot of static methods for jobs to be done. If its simply a job where I need no response or status, I do something simple like below. As you can see I can choose to call either ResizeImages or ResizeImagesAsync depending if I want to wait for it to finish or not
Code explanation: I use http://imageresizing.net/ to resize/crop images and the method SaveBlobPng is to store the images to Azure (cloud) but since that is irrelevant for this demo I didn't include that code. Its a good example of time consuming tasks though
private delegate void ResizeImagesDelegate(string tempuri, Dictionary<string, string> versions);
private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions)
{
ResizeImagesDelegate worker = new ResizeImagesDelegate(ResizeImages);
worker.BeginInvoke(tempuri, versions, deletetemp, null, null);
}
private static void ResizeImages(string tempuri, Dictionary<string, string> versions)
{
//the job, whatever it might be
foreach (var item in versions)
{
var image = ImageBuilder.Current.Build(tempuri, new ResizeSettings(item.Value));
SaveBlobPng(image, item.Key);
image.Dispose();
}
}
Or going for threading so you dont have to bother with Delegates
private static void ResizeImagesAsync(string tempuri, Dictionary<string, string> versions)
{
Thread t = new Thread (() => ResizeImages(tempuri, versions, null, null));
t.Start();
}
ThreadPool.QueueUserWorkItem is the quickest way to get a process running on a different thread.
Be aware that UI objects have "thread affinity" and cannot be accessed from any thread other than the one that created them.
So, in addition to checking out the ThreadPool (or using the asynchronous programming model via delegates), you need to check out Dispatchers (wpf) or InvokeRequired (winforms).
In the end you will have to use some sort of threading. The way it basically works is that you start a function with a new thread and it will run until the end of the function.
If you are using Windows Forms then a nice wrapper that they have for this is call the Background Worker. It allows you to work in the background with out locking up the UI form and even provides a way to communicate with the forms and provide progress update events.
Background Worker
.NET got new keyword async for asonchrynous functions. You can start digging at learn.microsoft.com (async). The shortest general howto make function asonchrynous is to change function F:
Object F(Object args)
{
...
return RESULT;
}
to something like this:
async Task<Object> FAsync(Object args)
{
...
await RESULT_FROM_PROMISE;
...
return RESULT;
}
The most important thing in above code is that when your code approach await keyword it return control to function that called FAsync and make other computation until promissed value has been returned and procede with rest of code in function FAsync.