C# SetPropertyThreadSafe vs Invoke thread-safe calls - c#

Which of these two methods are better to update the UI from another thread?
(for me they work both, but which is safer?)
I would prefer the SetPropertyThreadSafe method as it needs less code.
1.
label1.SetPropertyThreadSafe(() => this.label1.Text, "New Value");
2.
if (label1.InvokeRequired)
{
label1.Invoke(new MethodInvoker(delegate {
label1.Text="New Value"; }));
}

SetPropertyThreadSafe is not a method built in to .NET, if you are using this implmentation
public static TResult GetPropertyThreadSafe<TControl, TResult>(this TControl self, Func<TControl, TResult> getter)
where TControl: Control
{
if (self.InvokeRequired)
{
return (TResult)self.Invoke(getter, self);
}
else
{
return getter(self);
}
}
Then the two examples you posted are doing the exact same thing so there is no difference.

If you head
1.
label1.SetPropertyThreadSafe(() => this.label1.Text, "New Value");
label2.SetPropertyThreadSafe(() => this.label1.Text, "New Value2");
and 2.
if (label1.InvokeRequired)
{
label1.Invoke(new MethodInvoker(delegate
{
label1.Text="New Value";
label2.Text="New Value2";
}));
}
Then (2) is clearly better as it has a much lower overhead. But in your case there is nothing to choose between them.
If you know you are on another thread, there is no need for the "if InvokeRequired".

Related

Invoke Best Practice

Every time I update the view of my program from a thread other than the element was created from, I use:
if (this.table.InvokeRequired)
{
this.table.Invoke(new MethodInvoker(delegate
{
this.table.Controls.Add(newRow);
this.table.Controls.SetChildIndex(newRow, this.table.Controls.Count);
}));
}
else
{
this.table.Controls.Add(newRow);
this.table.Controls.SetChildIndex(newRow, this.table.Controls.Count);
}
Even though this approach works fine, I doubt that it's the best-practice to do it that way since
this.table.Controls.Add(newRow);
this.table.Controls.SetChildIndex(newRow, this.table.Controls.Count);
is basically the same for invoking and not invoking.
Any ideas how I could improve that?
You can put it in a method, then the method can invoke itself:
public void addRow(Control newRow) {
if (this.table.InvokeRequired) {
this.table.Invoke(new MethodInvoker(addRow), new object[]{ newRow });
} else {
this.table.Controls.Add(newRow);
this.table.Controls.SetChildIndex(newRow, this.table.Controls.Count);
}
}
The syntax might not be exactly right, but roughly:
delegate void myedelegate(<mystuff>)
void UpdateSomething(<mystuff>)
if(this.invokerequired)
{
mydelegate updater = new mydeleate(UpdateSomething);
updater.invoke(new object[]{<mystuff>})
}
else
{
//doupdate
}
Also, see http://www.codeproject.com/Articles/37642/Avoiding-InvokeRequired for a good guide on invoke required practices

Removing Text with an Invoke?

So, the documentation that I've found online so far regarding the Invoke property doesn't seem to be particularly good, which is actually kind of annoying, believe it or not. I understand what Invoke does - you can't safely access the GUI directly, so an invoke does it in a safe way. That's fine, but I don't understand the variables that go into the method. If I wanted to, for instance, remove text from a listbox, how would I do that? I get about this far before I get a bit lost.
private void DoStuff(string TextIWouldBeRemoving)
{
if (listboxname.InvokeRequired)
{
listboxname.Invoke(SomeMysteriousParamaters, new object[] { TextIWouldBeRemoving )};
}
}
The first parameter is the method you want to safely invoke, the second parameter is an object array of the arguments to that method
So you would write:
private void DoStuff(string TextIWouldBeRemoving)
{
if (listboxname.InvokeRequired)
{
listboxname.Invoke(DoStuff, new object[] { TextIWouldBeRemoving )};
}
else
{
// Actually remove the text here!
}
}
Invoke is all about threading.
You need to do an invoke whenever you have created a separate thread in your code, and you need to update the User Interface elements from withing the code, that is executing in that newly create thread.
You can use a BeginInvoke, instead of a synchronous Invoke method. This article has a good example:
http://msdn.microsoft.com/en-us/library/0b1bf3y3.aspx
private void button1_Click(object sender, EventArgs e)
{
if (listBox1.InvokeRequired)
{
Action<string> d = DoAnything;
listBox1.Invoke(d, new object[] { "Item 1" });
}
else
DoAnything("Item 1");
}
void DoAnything(string itemText)
{
listBox1.Items.Remove(itemText);
}

c# class - make function or method call and pass control

I'm not sure if my title is really correct. I've looked around and searched but not found anything so please forgive me if my problem has been answered already.
What I would like to do is call a function but not have to come back to the calling line of code. e.g
public static void temp(obj) {
switch (obj.id) {
case "1" :
if(blah) {
obj.id = "2";
temp(obj);
}
break;
case "2" :
obj.response = "done";
break;
}
}
so basically I dont want to eventually come back to my temp(obj) in the first case and fully pass control. Does this make sense, is it even possible and my architecture is all wrong?
Thank you for your time.
Let me see if I understand the question:
You've got a function Foo(), which calls function Bar(). (I wanted to remove the recursion you had in your example for simplicity, please correct me if that was important.) When function Bar() returns, you want control to pass not back to Foo(), but to Foo's caller?
This is probably possible in lower-level languages, like C, by hacking the stack and not placing Foo()'s return address there, so that when Bar() tried to return, it would jump to Foo's caller instead.
However, in C#, no. The call stack is a stack, and control will pass back in order. The only thing you can do would be to put a return statement after each call to Bar().
Edit:
"recursive calls without them being recursive"
How about this:
bool doItAgain = true;
while(doItAgain)
{
doItAgain = false;
// process, with your switch statement or whatever.
if(...)
{
doItAgain = true;
continue; // if necessary, skip any code after this statement. May not be necessary if you have things set up right.
}
}
If this were C++, you could eliminate the break and let the case "1" fall through, but this is not allowed in C# switch statements.
public static void temp(obj) {
if (obj.id == "1") {
obj.id = "2";
temp(obj);
}
if (obj.id == "2")
obj.response = "done";
}
Do you need the recursive call? This code retains your recursive call and sets obj.response to "done" after changing obj.id to "2". However, obj.response is set twice because of the recursive call. What are you trying to do?
I'm not sure what you exactly intend, but it sounds like a callback to me. Here is one possible example:
void DoSome()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate { RunMe(); ReturnTo(); }));
}
void RunMe() { }
void ReturnTo() { }
You start in DoSome() and continue, when RunMe is finished ReturnMe is called.

Replacing all usages of a method (Introduce Indirection)

I am generally not very fond of refactoring tools. No need to get into details. Still, I occasionally try out new versions. Here is what I was trying to do while evaluating resharper 4.5 :
I needed to replace all usages of a method with a wrapper method (to be created) but I could not. I usually suck at noticing an obvious feature, is this the case? If resharper does not have this feature, do you know such tools?
Edit 2: Sample has been improved to include instance method calls.
Edit:
Here is a simple case to play.
static void Main(string[] args)
{
while(true)
{
if (Console.ReadKey().Key == ConsoleKey.Escape)
{
Thread.Sleep(10);
if (Quiting()) break;
}
Console.Beep(250, 50);
}
}
static bool Quiting()
{
if (Console.In.Peek() > 0)
{
Console.Beep(250, 150);
return false;
}
return true;
}
What I need is something like: (Edit2: added an instance sample)
private static StringBuilder _builder = new StringBuilder();
static void Main(string[] args)
{
while(true)
{
var key = Console.ReadKey();
if (key.Key == ConsoleKey.Escape)
{
Thread.Sleep(10);
if (Quiting()) break;
}
_builder.Append(" (").Append(key.KeyChar).Append(") ");
Beep(250, 50);
}
}
static bool Quiting()
{
if (Console.In.Peek() > 0)
{
Beep(250, 150);
_builder.Append('#');
return false;
}
return true;
}
static void Beep(int frequency, int duration)
{
// finally cursor ends up here
Console.Beep(250, 50);
}
Console.Beep calls are refactored. Next lets refactor StringBuilder.Append(char) :
class Program
{
private static StringBuilder _builder = new StringBuilder();
static void Main(string[] args)
{
while(true)
{
var key = Console.ReadKey();
if (key.Key == ConsoleKey.Escape)
{
Thread.Sleep(10);
if (Quiting()) break;
}
_builder.Append(" (").AppendUpper(key.KeyChar).Append(") ");
Beep(250, 50);
}
}
static bool Quiting()
{
if (Console.In.Peek() > 0)
{
Beep(250, 150);
_builder.AppendUpper('n');
return false;
}
return true;
}
static void Beep(int frequency, int duration)
{
// finally cursor ends up here
Console.Beep(250, 50);
}
}
static class StringBuilderExtensions
{
public static StringBuilder AppendUpper(this StringBuilder builder, char c)
{
return builder.Append(char.ToUpper(c));
}
}
Selecting from usages and maybe omitting common parameters (such as 250 above) or common instance parameters for non-extension statics shall make this feature more valuable. Hopefully, this clears up the question.
ReSharper doesn't have this as a single refactoring. I might do it as follows:
Select the contents of the method to be wrapped, and use Extract Method to create a new private method from the contents.
The original method is now a trivial wrapper around "itself". Rename it if you like, or manipulate it as you like (make it static, move to a different class, surround with try/catch, whatever).
EDIT:
Based on your edit, it seems you have an additional problem. Not only is Console.Beep not in the same class, it's not even in your class.
But if you don't mind a little search and replace, then you can put it into your own class, then proceed with the refactoring:
namespace Temporary {
public class Console {
public static void Beep(int x, int y) {System.Console.Beep(x,y);}
}
}
Then do a "Replace in Files" to replace Console.Beep with Temporary.Console.Beep, and proceed as above.
It's not included in any .NET refactoring IIRC, the tool which has such a refactoring is Eclipse, but not for .NET/C#
Assuming the wrapper method will be in the same class you can rename the current method to the name of the new wrapper method (ctrl+R+R in Resharper). This will rename all calls to this method in the solution as well. Then rename the original method back by hand (don't use Resharper or all the calls will get renamed back too) and add the wrapper method.
Based on your edit I think you will be out of luck to get the functionality that you want from any Visual Studio add-in that I've seen (beyond the simple find and replace which will get you some of the way there I guess).
Depending on how much time and effort you are willing to devote to this I'd imagine it's possible to use the DXCore framework and write a plugin that will do this kind of refactoring.
Resharper has a Search and Replace with Pattern feature. It can search and replace on patterns and expressions.
This would refactor all calls to Console.Beep() to your own method. It only replaces the usage if 250 is the first parameter:
However this would replace the usage of Console.Beep() within your own Beep method. You would have to manually replace that one usage.

Accessing Class members with Invoke from a different thread in C#

Note: Part of a series: C#: Accessing form members from another class and How to access form objects from another cs file in C#.
Hello,
The Idea is to notify the user using the memo when a packet is received/sent in a TCP Client.
After couple of fixes,the most suitable solution seemed to be this one
public string TextValue
{
set
{
this.Memo.Text += value + "\n";
}
}
That's how it's being called
var form = Form.ActiveForm as Form1;
if(form != null)
form.TextValue = "Test asdasd";
However,calling the code throws an exception ,because of Unsafe thread call.I found a solution at msdn,but I can't seem to acquire the method they've used there.
This is my remake,which doesn't work.
private void SetTextMemo(string txt)
{
if(this.Memo.InvokeRequired)
{
this.Invoke(SetTextMemo,txt); //error here
}
else
{
this.Memo.Text += txt + "\n";
}
}
errors:
Argument '1': cannot convert from 'method group' to 'System.Delegate'
Argument '2': cannot convert from 'string' to 'object[]'
Basically,I'm trying to access the Memo(or more likely said,add text to the memo) from another thread using Invoke.I never used it before,maybe that's why I misunderstand my mistake.
The easy way is:
this.Invoke((MethodInvoker)delegate {
this.Memo.Text += txt + "\n";
});
Which uses an anonymous method to do the job inline. Since you expect to be on another thread, you may as well just call Invoke - it is safe even from the UI thread.
If you're using C# 3.0 and the 3.5 framework try the following
if ( this.Memo.InvokeRequired ) {
this.Invoke((Action)(() => SetTextMemo(txt)));
}
Your implementation assumes that the method will not infinitely recurse because the behavior of the InvokeRequired property will prevent it. This assumption may proove to be true, but there's no problem coding the function to avoid this possibility entirely. Here's what I suggest:
private void SetMemo(string txt)
{
Memo.Text = txt;
}
private delegate void MemoSetter(string txt);
public void ThreadSafeSet(string txt)
{
Invoke(new MemoSetter(SetMemo), txt);
}
I used to handle all this cross-thread business, but recently I went with AOP, where you simply decorate a method to execute on the UI thread. Here's an example (from PostSharp):
public class FormsThreadAttribute : OnMethodInvocationAspect
{
public override void OnInvocation(MethodInvocationEventArgs eventArgs)
{
Form f = (Form)eventArgs.Delegate.Target;
if (f.InvokeRequired)
f.Invoke(eventArgs.Delegate, eventArgs.GetArgumentArray());
else
eventArgs.Proceed();
}
}

Categories

Resources