Is there a shorthand for Form.BeginInvoke? - c#

Quite often in my GUI code, I write something like this:
private void SecondTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (progressBar1.InvokeRequired)
{
progressBar1.BeginInvoke(new ElapsedEventHandler(SecondTimer_Elapsed), new[] {sender, e});
return;
}
//Code goes here
}
Of course, this is necessary if the app is multithreaded, as we need to marshall the thread that originally created the control. The thing is, it can be tedious to write the delegate and put the arguments into an array, and it takes up space in the top of every such event handler. Is there an attribute or something along those lines that will replace this code for you? Basically a label that says "if you're on the wrong thread, call me again on the GUI thread with the same args."

I don't know of anything quite like that, but this would probably be a useful extension method for you:
public static class Extensions
{
public static void Execute(this ISynchronizeInvoke invoker,
MethodInvoker action)
{
if (invoker.InvokeRequired)
{
invoker.BeginInvoke(action);
}
else
{
action();
}
}
}
Now this only works for parameterless delegates, of course... but with lambda expressions that needn't be a problem:
progressBar1.Execute(() => SecondTimer_Elapsed(sender, e));
This has the following advantages:
It's simple to write
You can't go wrong with the signature (you're not relying on late binding)
MethodInvoker is executed slightly more efficiently than other delegates, I believe
If you don't have much code to execute, you can write it inline in the lambda expression

You can tidy this up with extension methods:
// Extension methods.
public static void BeginInvoke(this ISynchronizeInvoke #this, MethodInvoker action) {
if (#this.InvokeRequired) #this.BeginInvoke(action);
else action();
}
public static void BeginInvoke<T1, T2>(this ISynchronizeInvoke #this, Action<T1, T2> action, T1 arg1, T2 arg2) {
if (#this.InvokeRequired) #this.BeginInvoke(action, new object[] { arg1, arg2 });
else action(arg1, arg2);
}
// Code elsewhere.
progressBar1.BeginInvoke(() => SecondTimer_Elapsed(sender, e));
// Or:
progressBar1.BeginInvoke(SecondTimer_Elapsed, sender, e);
Edit: Jon Skeet is correct in saying that using the MethodInvoker delegate is faster. From the MSDN:
A call to an EventHandler or MethodInvoker delegate will be faster than a call to another type of delegate.

Grab an AOP framework for this. You can create an MethodInterceptionAspect that fires when a function is called. Then you can do the checks, and either toss the function (you have a ref to the function and it's arguments) to the GUI thread, or execute it directly.
Advantage is that you will have to write this code once, and can apply it to every property needed with just an attribute.

Related

C# delegates and why do we need them?

I am trying to understand "callback pattern". Every answer says that this is done with delegates (which I know them). But the codes on the answers are something like that:
public delegate void Callback(string result);
public void Test()
{
CallBack callback = CallbackFunction;
DoWork(callback);
}
public void DoWork(CallBack callback)
{
callback("Hello world");
}
public void CallbackFunction(string result)
{
Console.WriteLine(result);
}
I really don't understand, why we need delegate for this? We can do this in this way too?
public void Test()
{
DoWork();
}
public void DoWork()
{
CallbackFunction("Hello world");
}
public void CallbackFunction(string result)
{
Console.WriteLine(result);
}
Besides that, for example in Java, a callback means a real "return" to the main program's "particular function" after an event. But when we use delegates, isn't this just calling another method?
How can we make a callback that finally calls an OnFail() method on fail, and OnSuccess() method on success. I am really confused. Can somebody help me to understand this?
A delegate safely encapsulates a method, a kind of a template to a function in its signature. Sometimes it is easy to think it is a pointer to a function.
In your sample, the CallbackFunction can be setted to Callback because both in its definition takes just a string argument.
You could use Action and Func instead of delegate. The difference between them is that an Action does not return something and Func does. For sample:
public void Test(Action success, Action<Exception> error)
{
try
{
// perform some task
success();
}
catch (Exception ex)
{
error(ex);
}
}
And use it:
Test(() => { Console.WriteLine("Success"); },
(ex) => { Console.WriteLine($"Error: {ex.Message}"); });
the generic option of an Action is the type of the arguments you can pas to this method. On the sample, Exception is a argument which is passed to error Action. The same is valid for a Func<> but the last type of a Func is the result type.
Why do we need delegates?
Because in many programs, you need the ability to abstract the concept of a method. One reason is events, another is a set of methods like this:
public void DoWork(Action completeCallback)
{
... //Do Stuff
completeCallback();
}
public void FirstMainMethod()
{
DoWork(() => Console.WriteLine("First callback");
}
public void SecondMainMethod()
{
DoWork(() => Console.WriteLine("Second callback");
}
In other words, different parts of my code need to have a different method run on completion, so I pass it in (I can't use a direct call). The delegate abstraction allows this. Also note that the idea of a "completion" callback in .NET is pretty silly, you almost never need it. You will use delegates for this general idea all the time though.
How can we make a callback that finally calls an OnFail() method on fail, and OnSuccess() method on success?
You can do this pretty easily. You can even make a somewhat generic one (not sure if you would ever want to mind you, but the following code works):
public void SuccessFailHelper(Func<bool> work, Action success, Action failure)
{
if (work())
success();
else
failure();
}

How do I pass a method as the parameter of another method using linq expressions

I want to create a method that runs another method in a background thread. Something like this:
void Method1(string param)
{
// Some Code
}
void Method2(string param)
{
// Some Code
}
void RunInThread(AMethod m)
{
//Run the method in a background thread
}
If your method has return value use Func delegate otherwise you can use Action delegate. e.g:
void Method1(string param)
{
// Some Code
}
void Method2(string param)
{
// Some Code
}
void RunInThread(Action<string> m)
{
//Run the method in a background thread
}
Then you can call RunInThread this way:
RunInThread(Method1);
RunInThread(Method2);
I like Task.Run When I just want a little bit of code to run in the background thread. It even looks like it has nearly the same signature as what you're trying to define. Lots of other overloads too.
Task.Run(()=>{
//background method code
}, TResult);
MSDN documentation

Is it bad form to use a generic callback?

I've got this code (well, something similar).
private delegate void GenericCallback<T>(T Info);
private void DoWork()
{
System.Threading.Thread Worker = new System.Threading.Thread(
delegate()
{
TestMethod(TestMethodCallback<string>);
}
);
Worker.Start();
}
private void TestMethod(GenericCallback<string> Callback)
{
System.Threading.Thread.Sleep(1000);
if(Callback != null)
{
Callback("Complete");
}
}
private void TestMethod(GenericCallback<int> Callback)
{
System.Threading.Thread.Sleep(1000);
if(Callback != null)
{
Callback(25);
}
}
private void TestMethodCallback<T>(T Info)
{
MessageBox.Show(Info.ToString());
}
Which allows me to call different versions of TestMethod based on the type of a parameter, while also allowing me to have a single callback method.
Is this bad form, or an accepted practice?
It looks like you might be looking for the Action delegate type. It's basically what you have here: a generic void-returning delegate type.
Such an established practice, that some of the work has been done for you. Action in this case, and Func should you return a value, are generic delegates, precisely like this. An advantage is, if I saw your signature:
private void TestMethod(GenericCallback<string> Callback)
I have to look up what GenericCallback<string> is. If I saw:
private void TestMethod(Action<string> callback)
I already know.
Totally fine. In this very simple case it might be preferable to specify a string (since your generic type, with no constraints, can only be dealt with as an Object and so ToString() is one of the very few useful things you can call no matter what you pass), but obviously this is example code so there are very many accepted ways to do this. Action<> and Func<> are indeed good built-ins to know about, but they have some drawbacks, such as reduced self-documentation (it can be difficult to tell what a Func is expected to do, other than the obvious "take an integer and return an integer".
Assuming that this would be used for returning data asynchronously (otherwise, why not wait for the return value?), it sounds like you haven't discovered Task Parallel Library. In particular, Task<T> is a more generalized way of acheiving callback-like behaviour.
For instance:
private Task<int> TestMethod()
{
TaskCompletionSource<int> tcs=new TaskCompletionSource<int>();
//do something asynchronous
//when asynchronous job is complete
//tcs.SetResult(25);
return tcs.Task;
}

How can I use delegates to pass methods in a thread wrapper class?

I'm currently self-teaching myself C# and I'm a bit new at programming so apologies in advance if this is covered in another topic (I tried searching).
I've been trying to make a generic worker / thread class that takes in a method which specifically wraps around a long set of procedural steps. The idea is to be able to pause/resume it a manner similar to setting breakpoints to pause/unpause in Visual Studio. To provide context, I'm mostly working with automation with an ASP.NET and XAML WPF interface (XAML at the moment).
My understanding is that I need to use delegates of some sort but I'm looking for a very simple example in plain English. The examples I found are a completely different scope and I have a hard time following the provided solutions in other contexts.
From other examples on MSDN and Stackoverflow, the "Task" worker class is what I have so far, but I'm a bit at a loss on where to on DoDelegatedMethod and my constructor. What I'm trying to do here is to instantiate a Task object, pass in a delegated method on new instantiation, create a new thread, and marry the passed in method to the thread.
The reason why I want a general "Task" is so I can manage specific methods generically instead of having to write a different "DoWork" method for each instance.
Is this the right approach?
class Task
{
private ManualResetEvent _shutdownFlag = new ManualResetEvent(false);
private ManualResetEvent _pauseFlag = new ManualResetEvent(true);
private delegate void MyDelegate();
Thread _thread;
public Task() { }
public Task(MyDelegate d = new MyDelegate(DoStuff)) // ERROR
{
_thread = new Thread(DoDelegatedMethod); // ERROR
}
public void Start()
{
_thread.Start();
}
public void Resume()
{
_pauseFlag.Set(); ;
}
public void Stop()
{
_shutdownFlag.Set();
_pauseFlag.Set();
_thread.Join();
}
private void DoDelegatedMethod(MyDelegate d)
{
do
{
d();
}
while (!_shutdownFlag.WaitOne(0));
}
// This does nothing but spin forever until I force it to stop
public void Spin()
{
do
{
// MessageBox.Show("test");
_pauseFlag.WaitOne(Timeout.Infinite);
}
while (!_shutdownFlag.WaitOne(0));
//MessageBox.Show("thread over");
}
}
new Thread() takes a ThreadStart (or ParameterisedThreadStart) argument, and your DoDelegatedMethod callback doesn't have the right signature for ThreadStart. So you need to write something like this:
ThreadStart method = new ThreadStart(() => DoDelegatedMethod(d));
_thread = new Thread(method);
This creates an anonymous callback (the () => DoDelegatedMethod(d) bit) which when run will call DoDelegatedMethod with the delegate d (which is 'captured' by the anonmyous method). Now you pass this anonymous callback to the Thread constructor, so when the thread runs, it will call the anonymous callback, which will in turn call DoDelegatedMethod(d). Effectively the lambda adapts DoDelegatedMethod to the ThreadStart signature.
Another way to do this would be to change DoDelegatedMethod to take no arguments, and store d as a member field of the Task class which DoDelegateMethod would access.
Also, the reason you get an error on your constructor is that default values can only be of a limited set of types, and delegates aren't one of them (only types that are allowed in attributes, like int, long, string and Type are permitted). Use an overload instead:
public Task() : this(new MyDelegate(DoStuff)) { ... }
public Task(MyDelegate d) { ... }
Note you may still get an error if DoStuff is an instance method of Task -- it's not clear. Personally I think having a default delegate for Task to run is a bit of an odd design, so you may just want to get rid of the default constructor.
Following the discussion in the comments I thought it was worth summarising the suggested revisions to the Task class:
public class Task
{
private readonly Action _action;
// other members as before
// default constructor removed
public Task(Action action)
{
_action = action;
}
public void Start()
{
ThreadStart ts = new ThreadStart(DoDelegatedMethod);
_thread = new Thread(ts);
_thread.Start();
}
private void DoDelegatedMethod()
{
do
{
_action();
}
while (!_shutdownFlag.WaitOne(0));
}
// other members as before
}
And the usage:
Task task = new Task(this.AutomatedTasks);
task.Start();
private void AutomatedTasks() { ... }
You may find good implementation of Task Pool manager here
www.codeproject.com/KB/threads/smartthreadpool.aspx
smartthreadpool allows to send in pool any task,
but you have to add Pause\Start functions to it.
I would model this a List which I would enumerate like you would any other list and use 'yield' at the en of the enumerator.

Performance issues when updating UI without checking InvokeRequired first?

I have gotten a bit lazy(it's sometimes good) and started updating WinForms UI by invoking a callback without checking InvokeRequired first.
Are there a performance issues or considerations that I should be aware of?
private delegate void SetStatusEventHandler(string statusMessage);
private void SetStatus(string statusMessage)
{
Invoke((MethodInvoker) (() =>
{
resultLabel.Text = statusMessage;
}));
// - vs -
if (InvokeRequired)
{
SetStatusEventHandler cb = SetStatus;
Invoke(cb, statusMessage);
}
else
{
resultLabel.Text = statusMessage;
}
}
[EDIT]: Most of times that a method that calls "invoke" will be called at most like say 10~20 times a second with a wide interval inbetween.
[UPDATE] Settled with the following extension method
public static class SmartInvoker
{
public static void InvokeHandler(this Control control, MethodInvoker del)
{
if (control.InvokeRequired)
{
control.Invoke(del);
return;
}
del();
}
}
...
private void SetStatus(string statusMessage)
{
this.InvokeHandler(() => resultLabel.Text = statusMessage);
}
I guess finding out how to manage extension method classes is another topic I need to dig in. Thank you for your help
EDIT: See the comments for debate about the whole posting vs immediately dispatching malarky.
Either way, my answer is actually the same: unless this is happening hugely often unnecessarily (i.e. most of the time you're on the UI thread to start with, and it's attached to something like a mouse movement handler) I wouldn't worry. It certainly makes the code simpler. If this is going to be invoked very often, I'd measure and test more :)
Invoke is faster with an EventHandler or MethodInvoker delegate than with others. I don't know if there's any difference between the two - you may want to check.
You can make this even simpler by writing an extension method, e.g.
public static void InvokeHandler(this Control control, MethodInvoker handler)
{
control.Invoke(handler);
}
Then you can make your code:
private void SetStatus(string statusMessage)
{
this.InvokeHandler(delegate
{
resultLabel.Text = statusMessage;
});
}
or
private void SetStatus(string statusMessage)
{
InvokeHandler(() => resultLabel.Text = statusMessage);
}
That way you don't need to specify the delegate type.
Why not just add an extension method so you don't have to think about it anymore?
public static object SmartInvoke(this Control control, MethodInvoker del) {
if ( control.InvokeRequired ) {
control.Invoke(del);
return;
}
del();
}
Now your code becomes
private void SetStatus(string statusMessage) {
this.SmartInvoke(() => resultLabel.Text = statusMessage);
}
I believe it just prevents an unnecessary post if you're already on the same thread. So if that would be the most common scenario (being on the correct thread), it might cause a small performance hit by not checking, but I dont believe its actually required.

Categories