new thread causes "Method Name Expected" error - c#

I'm trying to call buildRangedJobCache with SelectionRange S as the passed in parameter, But the Compiler(visual studio 2010) gives the error: Method Name Expected below is the call that gives issue:
private void retrieveSeveralDaysJobs(SelectionRange S)
{
ignoreUpdates = false;
this.SetStatus(DataLogUIStrings.strRetrievingJobInformation);
Thread buildIndexThread = new Thread(new ThreadStart(buildRangedJobCache(S)));
buildIndexThread.Priority = ThreadPriority.Lowest;
buildIndexThread.Start();
}
and here is the function buildRangedJobCache(SelectionRange S):
private void buildRangedJobCache(SelectionRange S)
{
this.Cursor = Cursors.AppStarting;
try
{
if (DataStore == null)
{ throw new Exception("Error: DataStore is null, Unable to retrieve jobs."); }
lock (((ICollection)jobs).SyncRoot)
{
for (DateTime Day = S.Start; Day <= S.End; Day.AddDays(1))
{
this.RangeJobs.AddRange(DataStore.GetJobsListForDay(JobDateToDisplay.GetValueOrDefault(DateTime.Today)));
}
}
this.SetStatus(string.Format(DataLogUIStrings.strRetrievedSummaryInformation, this.jobs.Count));
}
catch (Exception e)
{
Log.Write(e);
}
this.Cursor = Cursors.Default;
}
also I've linked to here: Delegate: Method name expected error
as this solution didn't work for me.
**update: apparently it isn't clear, the solution of putting:
Thread buildIndexThread = new Thread(new ThreadStart(buildRangedJobCache));
does the same issue.

Pass only method name when creating delegate:
Thread buildIndexThread = new Thread(new ThreadStart(buildRangedJobCache));
Also ThreadStart delegate should not receive any arguments. It is defined as
public delegate void ThreadStart();
So, your buildRangedJobCache method signature do not match ThreadStart delegate signature. If you want to pass some parameters to thread, you should use ParameterizedThreadStart delegate, which accepts parameter of type object:
private void retrieveSeveralDaysJobs(SelectionRange range)
{
ignoreUpdates = false;
this.SetStatus(DataLogUIStrings.strRetrievingJobInformation);
// pass ParameterizedThreadStart delegate
Thread buildIndexThread = new Thread(BuildRangedJobCache);
buildIndexThread.Priority = ThreadPriority.Lowest;
buildIndexThread.Start(range); // provide parameter for thread
}
private void BuildRangedJobCache(Object obj)
{
SelectionRange range = (SelectionRange)obj; // cast to your type
// code
}

The Thread constructor requires a delegate (either ThreadStart or ParametrizedThreadStart). You're trying to create the ThreadStart delegate, but you can create a delegate out of a method, not method invocation expression.
So, if your method didn't have a parameter, the following would work:
new Thread(new ThreadStart(buildRangedJobCache));
and so would (because the compiler can infer which delegate are you creating):
new Thread(buildRangedJobCache);
If you need to pass a parameter to your method, you can use ParametrizedThreadStart and the overload of Start() that takes a parameter. But this means you have to change your method to have object parameter and cast it to your type inside the method.
I think a better option would be to use a lambda:
new Thread(() => buildRangedJobCache(S));
This creates an anonymous method that matches ThreadStart and remembers the variable S. This way, you don't need the signature of your method and you also don't need any casting.

Related

Initializing a task with an Action that invokes with an int parameter

I have following constructor in my class, which initializes my task:
public ReportGeneratorThread(Func<int, bool> getPermission, Action<object> a)
{
this.action = a;
this.t = new Task(this.action = this.InvokedAction, this.cancellationToken);
this.getPermission = getPermission;
}
The InvokedAction method, which will be invoked by the task is defined such as:
private void InvokedAction(object obj)
{
Debug.WriteLine(DateTime.Now.ToLongTimeString() + " Task " + this.t.Id + " has STARTED Generating a report");
this.GenerateReport();
throw new ArgumentException("For testing purpose");
}
The problem occurs when I want to invoke this method with an int rather than an object, since this is not accepted by the task. Is there any approach of how I can invoke this method with an int value with an:
Action<int>
Since you can't call Action<int> with argument of type object you need to convert it manually. Note that it would be fine if requirement is other way around - you can easily pass Action<object> where Action<int> is expected.
... new Task( v => intAction((int)v),...
You may need to handle cast exceptions if you can't guarantee that argument is always integer.
Can you box your int before invoking?
int i = 123;
object o = i;

Assigning code to a variable

Is it possible to make a variable, and assign a line of code to it, such as:
ButtonClicked = (MessageBox.Show("Hello, World!"));
... so when I use the variable, it will execute the line of code.
You could assign it to an Action like this:
var ButtonClicked = new Action(() => MessageBox.Show("hi"));
Then call it:
ButtonClicked();
For completeness (in regards to the various comments)...
As Erik stated, you could execute multiple lines of code:
var ButtonClicked = new Action(() =>
{
MessageBox.Show("hi");
MessageBox.Show("something else"); // something more useful than another popup ;)
});
As Tim stated, you could omit the Action keyword
Action ButtonClicked = () => MessageBox.Show("hi");
Action ButtonClicked = () =>
{
// multiple lines of code
};
To address KRyan's comment, regarding the empty parentheses, that represents the list of parameters you want to be able to send to the Action (in this case, none).
If, for instance, you wanted to specify the message to show, you could add "message" as a parameter (note that I changed Action to Action<string> in order to specify a single string parameter):
Action<string> ButtonClicked = (message) => MessageBox.Show(message);
ButtonClicked("hello world!");
In your case, you want to use a delegate.
Let's see how a delegate works and how we can get to an easier form by understanding its concept:
// Create a normal function
void OnButtonClick()
{
MessageBox.Show("Hello World!");
}
// Now we create a delegate called ButtonClick
delegate void ButtonClick();
You see, the delegate takes the form of a normal function but without any arguments (It could take any amount of arguments just like any other method, but for the sake of simplicity, it doesn't).
Now, let's use what we have; we will define the delegate just as we define any other variable:
ButtonClick ButtonClicked = new ButtonClick(OnButtonClick);
We basically created a new variable called ButtonClicked, that has a type of ButtonClick (which is a delegate) and that when used, will execute the method in the OnButtonClick() method.
To use it we simply call: ButtonClicked();
So the whole code would be:
delegate void ButtonClick();
void OnButtonClick()
{
MessageBox.Show("Hello World!");
}
void Foo()
{
ButtonClick ButtonClicked = new ButtonClick(OnButtonClick);
ButtonClicked(); // Execute the function.
}
From here, we can move to lambda expressions and see how they could be useful in your situation:
There are many delegates already defined by .NET libraries, with some like Action, which do not accept any parameter and does no return a value. It is defined as public delegate void Action();
You can always use it to your needs instead of the need of defining a new delegate every time. In the previous context for example, you could had just written
Action ButtonClicked = new Action(OnButtonClick);
ButtonClicked();
which would had done the same.
Now that you saw different ways of how to use delegates, let's use our first lambda expression. Lambda expressions are anonymous functions; so, they are normal functions but without a name. They are of those forms:
x => DoSomethingWithX(x);
(x) => DoSomethingWithX(x);
(x,y) => DoSometingWithXY(x,y);
() => Console.WriteLine("I do not have parameters!");
In our case, we do not have any parameters so we will use the last expression. We can use this just as the OnButtonClick function, but we get the advantage of not having a named function. We can instead do something like this:
Action ButtonClicked = new Action( () => MessageBox.Show("Hello World!") );
or even easier,
Action ButtonClicked = () => MessageBox.Show("Hello World!");
then simply call ButtonClicked(); Of course you can also have multi-lines of code, but I do not want to confuse you more. It would look like this though:
Action ButtonClicked = () =>
{
MessageBox.Show("Hello World!");
};
ButtonClicked();
You could also play around, for example, you can execute a function like this:
new Action(() => MessageBox.Show("Hello World!"))();
Sorry for the long post, hope it was not too confusing :)
EDIT: I forgot to mention that an alternate form which, even though not often used, could make lambda expressions easier to understand:
new Action(delegate() {
Console.WriteLine("I am parameterless");
})();
Also, using generics:
// Defines a delegate that has one parameter of type string. You could pass as many parameters as you want.
new Action<string>(delegate(string x) {
Console.WriteLine(x);
})("I am a string parameter!");
In turn you could use lambda expressions, but you do not need (but might in some cases) to define the type of the parameter, for example, the code above could simply be written as:
new Action<string>(x => {
Console.WriteLine(x);
})("I am a string parameter!");
or:
new Action<string>(x => Console.WriteLine(x))("I am a string parameter!");
EDIT2:
Action<string> is a representation of public void delegate Action(string obj);
Action<string,string> is a representation of public void delegate Action(string obj, string obj2);
In general, Action<T> is a representation of public void delegate Action<T>(T obj);
EDIT3:
I know the post has been here for a while, but I think this is really cool to not mention:
You can do this, which is mostly related to your question:
dynamic aFunction = (Func<string, DialogResult>)MessageBox.Show;
aFunction("Hello, world!");
or simply:
Func<string, DialogResult> aFunction = MessageBox.Show;
aFunction("Hello, world!");
The Lazy class is specifically designed to represent a value that won't be computed until you ask for it. You construct it by providing a method that defines how it should be constructed, but it will handle executing that method no more than once (even in the face of multiple threads requesting the value) and simply returning the already constructed value for any additional requests:
var foo = new Lazy<DialogResult>(()=>MessageBox.Show("Hello, World!"));
var result = foo.Value;
The way I'm reading your question, this is in the context of GUI controls?
If this is in WPF, take a look at the "right" way to handle commands from controls:
http://msdn.microsoft.com/en-us/library/ms752308(v=vs.110).aspx
...but that can be a pain and overkill. For a simpler general case, you might be looking for an event handler, like:
myButton.Click += (o, e) => MessageBox.Show("Hello, World!");
That event handler can be handled a variety of ways. The above example uses an anonymous function, but you could also do:
Action<object, RoutedEventArgs> sayHello = (o, e) => MessageBox.Show("Hello, World");
myButton.Click += new RoutedEventHandler(sayHello);
...just like you were asking, with a function (or here, "Action", since it returns void) assigned as a variable.
You can assign C# code to a variable, compiling it at runtime and run the code:
Write your code:
// Assign C# code to the code variable.
string code = #"
using System;
namespace First
{
public class Program
{
public static void Main()
{
" +
"Console.WriteLine(\"Hello, world!\");"
+ #"
}
}
}
";
Create the provider and parameters of the compiler:
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
Define parameters of the compiler:
// Reference to System.Drawing library
parameters.ReferencedAssemblies.Add("System.Drawing.dll");
// True - memory generation, false - external file generation
parameters.GenerateInMemory = true;
// True - exe file generation, false - dll file generation
parameters.GenerateExecutable = true;
Compile assembly:
CompilerResults results = provider.CompileAssemblyFromSource(parameters, code);
Check errors:
if (results.Errors.HasErrors)
{
StringBuilder sb = new StringBuilder();
foreach (CompilerError error in results.Errors)
{
sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
}
throw new InvalidOperationException(sb.ToString());
}
Get assembly, type and the Main method:
Assembly assembly = results.CompiledAssembly;
Type program = assembly.GetType("First.Program");
MethodInfo main = program.GetMethod("Main");
Run it:
main.Invoke(null, null);
Reference:
http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime

Create and pass a action/delegate of a method at runtime to TaskFactory.StartNew method

I need to create and pass a action/delegate of a method at runtime to TaskFactory.Satrtnew method. In general I would do the following when i know the method to use.
public void SomeService(CancellationToken cToken)
{ }
var tasks = new Task[] {
Task.Factory.StartNew(() => SomeService(new CancellationToken())
};
In my case, when I to do this at runtime, where my method names comes from configuration file. The method exists but it would be assigned to task at runtime. I tried something like
var conn = bll.daService.DbConnection;
var currentType = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;
var method = currentType.GetMethod("SomeService");
Action<CancellationToken> action = (Action<CancellationToken>)
Delegate.CreateDelegate(typeof(Action<CancellationToken>),currentType,method);
Task.Factory.StartNew(action);
And also something like.
delegate void ServiceDelegate(CancellationToken cToken);
ServiceDelegate serDel = (ServiceDelegate)
Delegate.CreateDelegate(currentType,method);
Action ac = serDel(new CancellationToken());
Task.Factory.StartNew(ac);
None of them are working.It throws different kind of errors and exceptions.
EDIT: The following line throws exception "Type must derive from Delegate"
ServiceDelegate serDel = (ServiceDelegate)
Delegate.CreateDelegate(currentType,method)

TimerCallback not returning value C#

I am using System.Threading.Timer to create a timer that prints a string to a serial port and then reads from another serial port every second. I am trying to do this by sending arguments to my TimerCallback function. Below is my code where the timer is initialized and the code for the callback function.
Initialization:
TimerCallback tcb = Timer_func(buff_out, send_port, recv_port);
AutoResetEvent autoEvent = new AutoResetEvent(false);
Timer aTimer = new Timer(tcb,autoEvent,1000,1000);
Callback function:
public static TimerCallback Timer_func(string buff_out, SerialPort send_port, SerialPort recv_port)
{
string buff_in;
send_port.WriteLine(buff_out);
buff_in = recv_port.ReadLine();
Console.WriteLine(buff_in);
}
The initialization occurs in the Main() function, and both functions are in the same class.
When I compile the code as is I recieve error CS0161: "not all code paths return a value". In attempts to remedy this I've added return 1; to the end of that function but then I recieve error CS0029: "cannot explicitly convert type 'int' to 'System.Threading.Timer'.
What am I doing wrong, and how can I fix it. (New to C#). Thank you in advance!
You're misunderstanding delegates.
TimerCallback is a delegate type – a type that can hold a function.
TimerCallback can only hold functions with the signature
void MethodName(Object state)
When you write
public static TimerCallback Timer_func(...) { ... }
You just declared a function that returns a TimerCallback delegate.
Thus, your function must return a function that matches TimerCallback.
You can do that using an anonymous delegate:
return delegate (object state) {
string buff_in;
send_port.WriteLine(buff_out);
buff_in = recv_port.ReadLine();
Console.WriteLine(buff_in);
};

C# compiler oddity with delegate constructors

Based on the following question, I found some odd behaviour of the c# compiler.
The following is valid C#:
static void K() {}
static void Main()
{
var k = new Action(new Action(new Action(K))));
}
What I do find strange is the compiler 'deconstructing' the passed delegate.
The ILSpy output is as follows:
new Action(new Action(new Action(null, ldftn(K)), ldftn(Invoke)).Invoke);
As one can see, it automatically decides to use the Invoke method of the delegate. But why?
As it is, the code is unclear. Do we have a triply-wrapped delegate (actual) or is the inner delegate just 'copied' to the outer ones (my initial thought).
Surely if the intent was like the compiler emitted the code, one should have written:
var k = new Action(new Action(new Action(K).Invoke).Invoke);
Similar to the decompiled code.
Can anyone justify the reason for this 'surprising' transformation?
Update:
I can only think of one possible use-case for this; delegate type conversion. Eg:
delegate void Baz();
delegate void Bar();
...
var k = new Baz(new Bar( new Action (K)));
Perhaps the compiler should emit a warning if the same delegate types are used.
The spec (section 7.6.10.5) says:
The new delegate instance is initialized with the same invocation list as the delegate instance given by E.
Now suppose the compiler translated it to something similar to your suggestion of:
new Action( a.Target, a.Method)
That would only ever create a delegate with an invocation list of a single method call. For a multi-cast delegate, it would violate the spec.
Sample code:
using System;
class Program
{
static void Main(string[] args)
{
Action first = () => Console.WriteLine("First");
Action second = () => Console.WriteLine("Second");
Action both = first + second;
Action wrapped1 =
(Action) Delegate.CreateDelegate(typeof(Action),
both.Target, both.Method);
Action wrapped2 = new Action(both);
Console.WriteLine("Calling wrapped1:");
wrapped1();
Console.WriteLine("Calling wrapped2:");
wrapped2();
}
}
Output:
Calling wrapped1:
Second
Calling wrapped2:
First
Second
As you can see, the real behaviour of the compiler matches the spec - your suggested behaviour doesn't.
This is partly due to the somewhat odd "sometimes single-cast, sometimes multi-cast" nature of Delegate, of course...
When you try to treat a delegate as a method, the compiler actually uses the delegate's Invoke() method. So, for example, the two lines below compile to the exact same IL (both call Invoke()):
k();
k.Invoke();
I assume the oddity you're seeing is a consequence of this. The delegate constructor expects a method (or rather, a method group), but it gets a delegate instead. So it treats it as a method and uses the Invoke() method.
As for the meaning, it is delegate that calls delegate that calls the actual method. You can verify this yourself by accessing the delegate's Method and Target properties. In the case of the outer-most delegate, Method is Action.Invoke and Target the inner delegate.
delegate is a class
Action delegate has a constructor like so
public extern Action(object #object, IntPtr method);
Since K is a static method there is no need to pass object to inner most action instance as first argument and hence it passes null
Since second argument is pointer to function therefore it passes pointer of K method using ldftn function
for the remaining Action instances the object is passed is inner Action and the second parameter is the Invoke method since when you call a delegate you're actually calling the Invoke method
Summary
var action = new Action(K) => Action action = new Action(null, ldftn(K))
new Action(action) => new Action(action, ldftn(Action.Invoke))
I hope this explains what is happening?

Categories