Multi threading delegate issue, Method name expected? - c#

Right, this is my first venture into multi threading so could be something incredibly simple I'm missing but here goes...
I'm using thread pool to kick off a bunch of short running processes at the same time, each will be passed a URL to process/scrape for fb-tweets-google-plusones and return a result to my ReportProgress method by invoking the delegate ThreadDone but when passing in the processed object once the thread's done processing, i keep getting the error Method name expected but I'm passing in the method ReportProgress? I'm willing to bet (hoping) it's something incredibly simple that someone more experienced can spot right away. Here is what i have so far:
Delegate definition:
public delegate void ThreadDone(object sender, ScrapeResult scrapedResult);
DoWork:
public void DoWork(object sender)
{
while (true)
{
//lock the thread to prevent other threads from processing same job
lock (_threadLock)
{
string url = (string)sender;
result.URL = url;
if (chkFb.Checked)
{
result.Shares = grabber.GetFacebookShares(url);
}
if (chkTwitt.Checked)
{
result.Tweets = grabber.GetTweetCount(url);
}
if (chkPlusOne.Checked)
{
result.PlusOnes = grabber.GetPlusOnes(url);
}
this.Invoke(new ThreadDone(ReportProgress(sender, result))); //ERROR is on this line
}
Thread.Sleep(100);
}
}
ReportProgress:
private void ReportProgress(object sender, ScrapeResult scrapedResult)//<-- might not need?
{
progressBar.Value++;
ScrapeResult result = (ScrapeResult)sender;//ScrapedResult result = scrapedResult;
outputGrid.Rows.Add(result.URL, result.Shares, result.Tweets, result.PlusOnes);
outputGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
outputGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
}
Any help is greatly appreciated!

Change this:
this.Invoke(new ThreadDone(ReportProgress(sender, result)));
To:
this.Invoke(new ThreadDone(ReportProgress), sender, result);
The first parameter of Invoke() is the delegate, to build a delegate you do not need to give its parameters but only the method to call (that's why compiler says "method name expected") With new ThreadDone(ReportProgress) you create the new delegate and with 2nd and 3rd parameter of Invoke() you specify the parameters that will be passed to your delegate.

I would seriously consider using the TPL. Much cleaner to handle the finish of a task.

Related

How to run a method after a specific time interval?

It's clear: For example, imagine a button in my form. When a user clicks on the button, some void method should run after 30 seconds.
There would be a void method DoAfterDelay that takes two input parameter. The first one is the method to do (using delegates), and the other one is the time interval. So I'll have:
public delegate void IVoidDelegate();
static void DoAfterDelay(IVoidDelegate TheMethod, TimeSpan Interval)
{
// *** Some code that will pause the process for "Interval".
TheMethod();
}
So, I just need a piece of code to pause the process for a specific time interval. Heretofore, I used this code to do that:
System.Threading.Thread.Sleep(Interval);
But this code is no good for me, because it stops the whole process and freezes the program. I don't want the program to get stuck in the DoAfterDelay method. That's why the Thread.Sleep is useless.
So could anyone suggest a better way? Of course I've searched about that, but most of the solutions I've found were based on using a timer (like here for example). But using a timer is my last opinion, because the method should run once and using timers makes the program confusing to read. So I'm looking for a better solution if there is. Or maybe I have to use timers?
I guess I have to play with threads, but not sure. So I wonder if anyone could guide me to a solution. Thanks in advance.
Can you use a task?
Task.Factory.StartNew(() =>
{
System.Threading.Thread.Sleep(Interval);
TheMethod();
});
This is where you can use the async await functionality of .Net 4.5
You can use Task.Delay an give the delay in miliseconds.
This is a very clean way. ex:
private async void button1_Click(object sender, EventArgs e)
{
await Task.Delay(5000);
TheMethod();
}
There are several methods of creating thread but of course, it depends on what you are doing.
You can create a thread on the fly like this:
Thread aNewThread = new Thread(
() => OnGoingFunction()
);
aNewThread.Start();
This thread will be running in the background. The function you want to do should have a sleep method to sleep when its done processing. So something like this:
private void OnGoingFunction()
{
//Code....
Thread.Sleep(100); //100 ms, this is in the thead so it will not stop your winForm
//More code....
}
I hope that helps.
Another option is to create the thread whenever you need to process it and not worry about the sleep option. Just create a new thread every time to load the process
You should create a Coroutine
public IEnumerator waitAndRun()
{
// WAIT FOR 3 SEC
yield return new WaitForSeconds(3);
// RUN YOUR CODE HERE ...
}
And call it with:
StartCoroutine(waitAndRun());
DoAfterDelay starts a timer that just runs once, that when it expires it calls your void 'TheMethod'function.
Why would this be messy?
You can specify the exact seconds by using
DateTime runTime = new DateTime();
double waitSeconds = (runTime - DateTime.Now).TotalSeconds;
Task.Factory.StartNew(() =>
{
Thread.Sleep(TimeSpan.FromSeconds(waitSeconds));
YourMethod();
});
runTime => When you want to execute the method.
Here's what you want:
public static void Example1c()
{
Action action = DoSomethingCool;
TimeSpan span = new TimeSpan(0, 0, 0, 5);
ThreadStart start = delegate { RunAfterTimespan(action, span); };
Thread t4 = new Thread(start);
t4.Start();
MessageBox.Show("Thread has been launched");
}
public static void RunAfterTimespan(Action action, TimeSpan span)
{
Thread.Sleep(span);
action();
}
private static void DoSomethingCool()
{
MessageBox.Show("I'm doing something cool");
}
One of the benefits of using Action is that it can be easily modified to pass in parameters. Say you want to be able to pass an integer to DoSomethingCool. Just modify thusly:
public static void Example1c()
{
Action<int> action = DoSomethingCool;
TimeSpan span = new TimeSpan(0, 0, 0, 5);
int number = 10;
ThreadStart start = delegate { RunAfterTimespan(action, span, number); };
Thread t4 = new Thread(start);
t4.Start();
MessageBox.Show("Thread has been launched");
}
public static void RunAfterTimespan(Action<int> action, TimeSpan span, int number)
{
Thread.Sleep(span);
action(number);
}
private static void DoSomethingCool(int number)
{
MessageBox.Show("I'm doing something cool");
}
Very flexible...
Here's a simple extension against Dispatcher that you can use in a non-blocking way.
public static void InvokeAfter(this Dispatcher dispatcher, int milliseconds, Action delayedAction) {
Task.Factory.StartNew(() => {
System.Threading.Thread.Sleep(milliseconds);
dispatcher.Invoke(delayedAction);
});
}
And here's how you use it with a Lambda:
SomeLabel.Dispatcher.InvokeAfter(3000, () => {
SomeLabel.Text = "Hello World";
});
You can also use it with anything that matches Action. Here's an example using a local function...
void doLater(){
SomeLabel.Text = "Hello World";
}
// Pass the action itself, not the result of the action (i.e. don't use parentheses with 'doLater'.)
SomeLabel.Dispatcher.InvokeAfter(3000, doLater);
Note: You can then call it against any dispatcher object where you would normally call Invoke. For safety, I like to invoke it using the dispatcher handling the control I'm updating.

C# Is action.BeginInvoke(action.EndInvoke,null) a good idea?

If I want to do a "fire and forget" of some code, but still want to ensure that my memory is cleaned up (per Why does asynchronous delegate method require calling EndInvoke?), will the following achieve that goal?
Action myAction = () => LongRunTime();
myAction.BeginInvoke(myAction.EndInvoke,null);
I've looked around but haven't seen that pattern used anywhere. Rather, people use an annonomoyus method as their callback (such as The proper way to end a BeginInvoke?) or they define an actual callback method. Since I haven't seen anyone else do this, it makes me think it either doesn't work or is otherwise a bad idea.
Thanks!
Using a method group conversion instead of a delegate is fine, the EndInvoke will still be called in on your Action. There is nothing else to be done, since this is a fire and forget call.
Unfortunately, it's somewhat hard to directly irrefutably prove that EndInvoke is called, since Action is a delegate and we can't just add a breakpoint on some class in the BCL.
This code will (periodically) inspect some private field of the IAsyncResult that is returned by BeginInvoke, which seems to keep track of whether or not EndInvoke has been called yet:
public partial class MainWindow : Window
{
private Timer _timer = new Timer(TimerCallback, null, 100, 100);
private static IAsyncResult _asyncResult;
public MainWindow()
{
InitializeComponent();
}
static void LongRunTime()
{
Thread.Sleep(1000);
}
void Window_Loaded(object sender, RoutedEventArgs args)
{
Action myAction = () => LongRunTime();
_asyncResult = myAction.BeginInvoke(myAction.EndInvoke, null);
}
static void TimerCallback(object obj)
{
if (_asyncResult != null)
{
bool called = ((dynamic)_asyncResult).EndInvokeCalled;
if (called)
{
// Will hit this breakpoint after LongRuntime has completed
Debugger.Break();
_asyncResult = null;
}
}
}
}
I've double checked using SOS that there aren't any managed memory leaks. I've also tried several other proofs, but they were more circumstantial than this one, I think.
Some interesting I discovered during my investigation: the myAction.BeginInvoke call will show up on profilers using instrumentation, but myAction.EndInvoke does not.
Nowdays it could be done like
BeginInvoke((Action)(async () =>
{
// Show child form
var f = new MyForm();
f.ShowDialog();
// Update parent/current
await UpdateData();
}));

Using MethodInvoker without Invoke

I am writing GUI applications for some time now and one thing I always use are MethodInvoker + lambda functions to do cross-thread access.
From the examples I find I always see stuff like this:
Version 1
if (InvokeRequired)
{
Invoke(new MethodInvoker(() =>
{
Label1.Text = "Foobar";
});
}
else
{
Label1.Text = "Foobar";
}
However this leads to code-duplication --> major baddie to me.
So what's wrong with this?
Version 2
MethodInvoker updateText = new MethodInvoker(() =>
{
Label1.Text = "Foobar";
});
if (InvokeRequired)
{
Invoke(updateText);
}
else
{
updateText();
}
Now I have the functionality bundled in one variable and call it with Invoke or as a function pointer when appropriate. Is version 2 worse performance-wise? Or is i bad practice to use anonymous functions for this?
Nothing's wrong with it... but you can add an extension method to make it all somewhat nicer:
public static void InvokeIfNecessary(this Control control,
MethodInvoker action)
{
if (control.InvokeRequired)
{
control.Invoke(action);
}
else
{
action();
}
}
Then you can write:
this.InvokeIfNecessary(() => Label1.Text = "Foobar");
Much neater :)
There is a very slight performance drawback from creating a delegate when you don't need to, but it's almost certainly insignificant - concentrate on writing clean code.
Note that even if you don't want to do that, you can still make your variable declaration simpler in your existing code:
MethodInvoker updateText = () => Label1.Text = "Foobar";
That's one benefit of using a separate variable - you don't need the new MethodInvoker bit to tell the lambda expression what type of delegate you want...
Is version 2 worse performance-wise? Or is i bad practice to use anonymous functions for this?
No version 2 is better, don't worry about performance problems with it. Instead of using an anonymous function you could also define a method:
public void SetLabelTextToFooBar()
{
Label1.Text = "Foobar";
}
and then:
if (InvokeRequired)
{
Invoke(SetLabelTextToFooBar);
}
else
{
SetLabelTextToFooBar();
}
or simply use a BackgroundWorker which will automatically execute all callbacks (such as RunWorkerCompleted and ProgressChanged) on the main UI thread so that you don't need to check for InvokeRequired.
Another practice on doing it:
Invoke((MethodInvoker)delegate
{
Label1.Text = "Foobar";
});

MethodInvoker vs Action for Control.BeginInvoke

Which is more correct and why?
Control.BeginInvoke(new Action(DoSomething), null);
private void DoSomething()
{
MessageBox.Show("What a great post");
}
or
Control.BeginInvoke((MethodInvoker) delegate {
MessageBox.Show("What a great post");
});
I kinda feel like I am doing the same thing, so when is the right time to use MethodInvoker vs Action, or even writing a lambda expression?
EDIT: I know that there isn't really much of a difference between writing a lambda vs Action, but MethodInvoker seems to be made for a specific purpose. Is it doing anything different?
Both are equally correct, but the documentation for Control.Invoke states that:
The delegate can be an instance of
EventHandler, in which case the sender
parameter will contain this control,
and the event parameter will contain
EventArgs.Empty. The delegate can also
be an instance of MethodInvoker, or
any other delegate that takes a void
parameter list. A call to an
EventHandler or MethodInvoker delegate
will be faster than a call to another
type of delegate.
So MethodInvoker would be a more efficient choice.
For each solution bellow I run a 131072 (128*1024) iterations (in one separated thread).
The VS2010 performance assistant give this results:
read-only MethodInvoker: 5664.53 (+0%)
New MethodInvoker: 5828.31 (+2.89%)
function cast in MethodInvoker: 5857.07 (+3.40%)
read-only Action: 6467.33 (+14.17%)
New Action: 6829.07 (+20.56%)
Call to a new Action at each iteration
private void SetVisibleByNewAction()
{
if (InvokeRequired)
{
Invoke(new Action(SetVisibleByNewAction));
}
else
{
Visible = true;
}
}
Call to a read-only, build in constructor, Action at each iteration
// private readonly Action _actionSetVisibleByAction
// _actionSetVisibleByAction= SetVisibleByAction;
private void SetVisibleByAction()
{
if (InvokeRequired)
{
Invoke(_actionSetVisibleByAction);
}
else
{
Visible = true;
}
}
Call to a new MethodInvoker at each iteration.
private void SetVisibleByNewMethodInvoker()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(SetVisibleByNewMethodInvoker));
}
else
{
Visible = true;
}
}
Call to a read-only, build in constructor, MethodInvoker at each iteration
// private readonly MethodInvoker _methodInvokerSetVisibleByMethodInvoker
// _methodInvokerSetVisibleByMethodInvoker = SetVisibleByMethodInvoker;
private void SetVisibleByMethodInvoker()
{
if (InvokeRequired)
{
Invoke(_methodInvokerSetVisibleByMethodInvoker);
}
else
{
Visible = true;
}
}
Call to the function cast in MethodInvoker at each iteration
private void SetVisibleByDelegate()
{
if (InvokeRequired)
{
Invoke((MethodInvoker) SetVisibleByDelegate);
}
else
{
Visible = true;
}
}
Example of call for the "New Action" solution :
private void ButtonNewActionOnClick(object sender, EventArgs e)
{
new Thread(TestNewAction).Start();
}
private void TestNewAction()
{
var watch = Stopwatch.StartNew();
for (var i = 0; i < COUNT; i++)
{
SetVisibleByNewAction();
}
watch.Stop();
Append("New Action: " + watch.ElapsedMilliseconds + "ms");
}
I prefer using lambdas and Actions/Funcs:
Control.BeginInvoke(new Action(() => MessageBox.Show("What a great post")));
Action is defined in System, while MethodInvoker is defined in System.Windows.Forms - you may be better off using Action, since it is portable to other places. You will also find more places that accept Action as a parameter than MethodInvoker.
However, the documentation does indicate that calls to delegates of type EventHandler or MethodInvoker in Control.Invoke() will be faster than any other type.
Aside from which namepsace they are in, I don't believe there is a meaningful functional difference between Action and MethodInvoker - they are essentially both defined as:
public delegate void NoParamMethod();
As an aside, Action has several overloads which allow parameters to be passed in - and it is generic so that they can be typesafe.
Also per MSDN:
MethodInvoker provides a simple delegate that is used to invoke a method with a void parameter list. This delegate can be used when making calls to a control's Invoke method, or when you need a simple delegate but do not want to define one yourself.
an Action on the other hand can take up to 4 parameters.
But I don't think there is any difference between MethodInvoker and Action as they both simply encapsulate a delegate that doesn't take a paremter and returns void
If you look at their definitions you'll simply see this.
public delegate void MethodInvoker();
public delegate void Action();
btw you could also write your second line as.
Control.BeginInvoke(new MethodInvoker(DoSomething), null);
It is a matter of preference in most cases, unless you intend to reuse the DoSomething() method. Also the anonymous functions will place your scoped variables on the heap, might make it a more expensive function.
Don't forget to somehow check if control is available at the moment, to avoid errors at closing form.
if(control.IsHandleCreated)
control.BeginInvoke((MethodInvoker)(() => control.Text="check123"));

Example to see return value in multithread scenario

I have a method. I want to return a value not from the main thread but from separate thread. Can you give example of it?
Easiest way is to check out the Background Worker
//set up your BackgroundWorker
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
worker.RunWorkerAsync();
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result != null)
{
//process your e.Result
}
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
//do your work here
e.Result = "testing"; //set the result to any object
}
Your question does not make sense. A method returns a value directly to the method that called it, on the same thread.
EDIT: If you want a method to supply a value to the UI thread on WinForms, you can call the BeginInvoke method. For example,
//In some event handler, such as button1_Click:
ThreadPool.QueueUserWorkItem(delegate {
//This code runs on a background thread.
//In it, you can do something that takes
//a long time without freezing the UI. If
//you need to interact with the UI from
//the background thread, use the Invoke
//method, like this:
var text = (string)Invoke(new Func<string>(() => textBox1.Text));
//I assume you'd want to do something more meaningful.
var result = text + Environment.NewLine + new String(text.Reverse().ToArray());
//To send the result back to the UI thread, call BeginInvoke:
BeginInvoke(new Action(delegate {
//This code is back on the UI thread,
//but it can still use the variables
//defined earlier.
label1.Text = result;
});
});
Jon Skeet has an excellent article on threading within .net in general. However, if you would like a more specific answer to a more specific problem, please post more details.
EDIT:
To make have methods return in a thread other than the main thread, all you need is a second thread. Everything done in that thread will be method calls and returns in that separate thread. Passing data between threads is a much more complex and trick subject. As a starting point, again I point to Jon Skeet's article to get a good base understanding. Beyond that, there are general principles that can be helpful, like Asynchronous calls and BackgroundWorkers (also see here)that can be very helpful, but these are only options, there many ways to do this, and how it should be done is very dependent on the situation.
In order for your method to return something from another thread, that other thread must "have" the something, and must indicate that the "something" is ready to be returned. There is no general case of this, but there are specific cases. For instance, a producer/consumer problem where your other thread produces something and puts it into a queue, and the first thread waits until there's something in the queue, takes it out, then returns it.
Another case that makes a little sense is seen in asynchronous ASP.NET pages. The page starts its life normally, issues one or more asynchronous operations, and then returns back to ASP.NET. It does nothing else until all the asynchronous operations have completed. Then, ASP.NET calls a method in the page that retrieves the results of these operation and uses them in the rest of the page.
You may be able to see that these two cases are very different. That's because you seem to have asked a "learning" question that amounts to "I wonder if a method always has to get its return value from the same thread?" But that's not something you ever have to do in real life, not really.
I will add that the Ada programming language includes something like this - someone who's actually used it will have to say whether it was useful. If I recall correctly, one task can rendezvous with another, and pass data between them.
This does what you asked for:
class DoSomething
{
string result;
public void RunAsync()
{
var t = new BackgroundWorker();
t.DoWork += (sender, e) =>
{
result = string.Empty; // your code goes here instead of string.empty
};
t.RunWorkerCompleted += Finished;//BackgroundWorkerFinished(sender, e);
t.RunWorkerAsync();
}
public void Finished(object sender, RunWorkerCompletedEventArgs e)
{
//result has been set, now what?
}
}
Once you get that down this becomes more useful:
public static void RunAsync(this Action ActionToAsync, Action<object, RunWorkerCompletedEventArgs> FinishedAction)
{
var t = new BackgroundWorker();
t.DoWork += (sender, e) => ActionToAsync();
t.RunWorkerCompleted += (sender, e) => FinishedAction.Invoke(sender,e);//BackgroundWorkerFinished(sender, e);
t.RunWorkerAsync();
}

Categories