C# Threading arguments are invalid - c#

i got this Code from an Old post
public delegate void Worker();
private static Thread worker;
public static void Init(Worker work)
{
worker = new Thread(new ThreadStart(work));
worker.Start();
}
public static void Work()
{
string result = testing;
}
I modify the code by adding parameters , when i try to call Init("AA") I am getting an error "Best overload method has some invalid arguments"
The following is the edited code
public delegate void Worker();
private static Thread worker;
public static void Init(Worker work)
{
worker = new Thread(new ThreadStart(work));
worker.Start();
}
public static void Work(string testing)
{
string result = testing;
}

Your Init method takes a delegate and you are passing a string, that is why there is no overload.
you want to do : Init(Work)
PS : your issue has nothing to do with threading.

The problem is your Worker delegate expect take a string parameter. You need to update that and then pass in the parameter e.g.
public delegate void Worker(string str);
private static Thread worker;
public static void Init(Worker work)
{
worker = new Thread(work);
worker.Start("AA");
}
public static void Work(string testing)
{
string result = testing;
}

If you want to pass some data to thread you can use ParametrizedThreadStart, or anonymous method:
private static Thread worker;
public static void Init(string testing)
{
// passing anonymous method, which will capture parameter
worker = new Thread(() => Work(testing));
worker.Start();
}
public static void Work(string testing)
{
string result = testing;
}
private static Thread worker;
public static void Init(string testing)
{
// passing PrametrizedThreadStart delegate
worker = new Thread(Work);
worker.Start(testing); // passing parameter
}
// PrametrizedThreadStart delegate accepts object as parameter
public static void Work(object testing)
{
string result = (string)testing;
}

Related

Why is my `StandardOleMarshalObject` COM Object called from multiple threads?

I have a COM object which is implemented in C#, and inherits from StandardOleMarshalObject to disable the NTA default behavior. For some reason, when I make a call to a server that makes a reentrant call to the client, the callback ends up on a different thread.
How do I ensure that all calls are made on the main thread?
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IComChat
{
void WriteLine(string text);
void Subscribe(IComChat callback);
}
public class ComChatServer : StandardOleMarshalObject, IComChat
{
private List<IComChat> Clients = new List<IComChat>();
public void WriteLine(string text)
{
foreach (var client in Clients)
{
// this makes a reentrant callback into the calling client
client.WriteLine(text);
}
}
public void Subscribe(IComChat client) => Clients.Add(client);
}
public class ComChatClient : StandardOleMarshalObject, IComChat
{
private IComChat Server;
private Thread MainThread;
public ComChatClient()
{
this.MainThread = Thread.CurrentThread;
this.Server = /* get server by some means */;
this.Server.Subscribe(this);
}
void IComChat.WriteLine(string text)
{
// this throws as the call ends up on a different thread
Contract.Assert(Thread.CurrentThread == MainThread);
Console.WriteLine(text);
}
void IComChat.Subscribe(IComChat callback) => throw new NotSupportedException();
public void WriteLine(string text) => Server.WriteLine(text);
}
public static class Program
{
public static void Main(string[] args)
{
var client = new ComChatClient();
Application.Run(new ChatWindow(client));
}
}
StandardOleMarshalObject only keeps things on the main thread if you create the object on a STA thread. Mark your entrypoint with [STAThread] to set your main thread as being single-threaded:
public static class Program
{
[STAThread]
public static void Main(string[] args)
{
var client = new ComChatClient();
Application.Run(new ChatWindow(client));
}
}

Start thread with parameters

I need to abort a thread if the code takes more than 3 seconds to execute. I am using the below method.
public static void Main(string[] args) {
if (RunWithTimeout(LongRunningOperation, TimeSpan.FromMilliseconds(3000))) {
Console.WriteLine("Worker thread finished.");
} else {
Console.WriteLine("Worker thread was aborted.");
}
}
public static bool RunWithTimeout(ThreadStart threadStart, TimeSpan timeout) {
Thread workerThread = new Thread(threadStart);
workerThread.Start();
bool finished = workerThread.Join(timeout);
if (!finished)
workerThread.Abort();
return finished;
}
public static void LongRunningOperation() {
Thread.Sleep(5000);
}
Can you please tell how can I do the same thing for the function having parameters. For example:
public static Double LongRunningOperation(int a,int b) {
}
You need to create a class that'll contain the 2 int parameters and then use ParametrizedThreadStart and pass in your object
See ParameterizedThreadStart
If you are using .Net>=4.0 You can also use TPL
Task.Factory.StartNew(()=>LongRunningOperation(a,b));
--EDIT--
Per your edit(answer)
Change your code as below
if (RunWithTimeout(new ParameterizedThreadStart(LongRunningOperation), TimeSpan.FromMilliseconds(3000)))
and
public static void LongRunningOperation(object ao){.....}

Why Does ParameterizedThreadStart Only Allow Object Parameter?

Please let me know why ParameterizedThreadStart class only allow method which only System.object argument type contain.
public class MainThreadTest
{
public static void Main(string[] args)
{
Thread T = new Thread(new ParameterizedThreadStart(DisplayYOrX));
T.Start("X");
DisplayYOrX("Y");
}
static void DisplayYOrX(object outValue)
{
string Parameter = (string)outValue;
for(int i=0; i<10; i++)
Console.Write(Parameter);
}
}
Why I would like to know about that is I do not want to use type cast syntax again.
string Parameter = (string)outValue;
The reason for the limitation is that ThreadStart isn't a generic delegate and hence it's only capable of passing an object around. This is easy enough to work around though by using a lambda where you directly pass the value.
public static void Main(string[] args) {
ThreadStart start = () => {
DisplayYOrX("X");
};
Thread t = new Thread(start);
t.Start();
...
}
static void DisplayYOrX(string outValue) {
...
}
Version for C# 2.0
public static void Main(string[] args) {
ThreadStart start = delegate {
DisplayYOrX("X");
};
Thread t = new Thread(start);
t.Start();
...
}

DispatcherObject inheritance and usage...what am I not getting?

So here is my code:
class Program
{
static DispatchClass dc;
[STAThread]
static void Main(string[] args)
{
dc = new DispatchClass();
Thread th = new Thread(AccessDC);
th.Start();
Console.ReadKey();
}
private delegate void AccessDCDelegate(object state);
static private void AccessDC(object state)
{
if(dc.Dispatcher.CheckAccess())
dc.Print("hello");
else
dc.Dispatcher.Invoke(new AccessDCDelegate(AccessDC));
}
}
public class DispatchClass : DispatcherObject
{
public void Print(string str)
{
Console.WriteLine(str);
}
}
Now...the output I would expect from this is for the created thread to check the dispatcher access, see that it is on a different thread and then invoke AccessDC(...) on the original thread which then checks and sees that it is on the correct thread and calls dc.Print(...).
What actually happens is it gets to CheckAccess() and correctly sees that it isn't on the correct thread, then calls Invoke(...) and stops there.
Any insight into how Dispatchers work would be greatly appreciated.
Thanks.
The dispatcher requires a message pump, console apps do not have a message pump by default. Try running this as a GUI application instead - that will have a message pump.
CheckAccess verified that your CurrentThread DispatchClass is the current thread so it returned to you False. which is quite normal.
In this snippet of code
dc.Dispatcher.Invoke(new AccessDCDelegate(AccessDC));
You have a problem with arguments that's all.
this snippet of code works :
public partial class MainWindow : Window
{
static DispatchClass dc;
public MainWindow()
{
InitializeComponent();
dc = new DispatchClass();
Thread th = new Thread(AccessDC);
th.Start();
}
private delegate void AccessDCDelegate(object state);
static private void AccessDC(object state)
{
if (dc.Dispatcher.CheckAccess())
dc.Print("hello");
else
dc.Dispatcher.BeginInvoke(new Action(()=> AccessDC(null)));
}
}
public class DispatchClass : DispatcherObject
{
public void Print(string str)
{
MessageBox.Show(str);
}
}

C# Threading Mechanism

Let's say I have an exposed interface as such:
interface IMyService
{
MyResult MyOperation();
}
This operation is synchronous and returns a value.
My implemented interface has to do the following:
Call an asynchronous method
Wait for event #1
Wait for event #2
This is due to a 3rd party COM object I am working with.
This code looks similar to the following
public MyResult MyOperation()
{
_myCOMObject.AsyncOperation();
//Here I need to wait for both events to fire before returning
}
private void MyEvent1()
{
//My Event 1 is fired in this handler
}
private void MyEvent2()
{
//My Event 2 is fired in this handler
}
My two events can happen in either order, it is quite random.
What is the proper threading mechanism I can use to synchronize this? I was using ManualResetEvent before I had to start waiting for the second event, and have not seen an easy way to use it for both events. These 2 events set variables that allow me to create the return value for MyOperation().
Any ideas on a good implementation for this? I have no control over the way the 3rd party object is implemented.
Two ManualResetEvents should do the trick for you. Just initialize them to false before you call the _myCOMObject.AsyncOperation(). Like this:
private ManualResetEvent event1;
private ManualResetEvent event2;
public MyResult MyOperation()
{
event1 = new ManualResetEvent(false);
event2 = new ManualResetEvent(false);
_myCOMObject.AsyncOperation();
WaitHandle.WaitAll(new WaitHandle[] { event1, event2 });
}
private void MyEvent1()
{
event1.Set();
}
private void MyEvent2()
{
event2.Set();
}
Edit
Thanks for the comments. I've changed the wait call to use WaitAll
My implementation example is as follows:
namespace ConsoleApplication1
{
class Program
{
private static WaitHandle[] waitHandles;
private static event EventHandler Evt1;
private static event EventHandler Evt2;
static void Main(string[] args)
{
waitHandles = new WaitHandle[]{
new ManualResetEvent(false),
new ManualResetEvent(false)
};
Evt1 += new EventHandler(Program_Evt1);
Evt2 += new EventHandler(Program_Evt2);
OnEvt1();
OnEvt2();
WaitHandle.WaitAll(waitHandles);
Console.WriteLine("Finished");
Console.ReadLine();
}
static void Program_Evt2(object sender, EventArgs e)
{
Thread.Sleep(2000);
((ManualResetEvent)waitHandles[0]).Set();
}
static void Program_Evt1(object sender, EventArgs e)
{
((ManualResetEvent)waitHandles[1]).Set();
}
static void OnEvt1()
{
if (Evt1 != null)
Evt1(null, EventArgs.Empty);
}
static void OnEvt2()
{
if (Evt2 != null)
Evt2(null, EventArgs.Empty);
}
}
}
I make it sleep for the purposes of this example and the WaitAll functionality
Cheers,
Andrew
P.S. another example would be using AsyncCallback, really quick and dirty example, but gives you more keys to open the door with :-) . Hope this helps!!
namespace ConsoleApplication1
{
class Program
{
private static WaitHandle[] waitHandles;
private static event EventHandler Evt1;
private static event EventHandler Evt2;
static void Main(string[] args)
{
waitHandles = new WaitHandle[]{
new ManualResetEvent(false),
new ManualResetEvent(false)
};
var callabck1 = new AsyncCallback(OnEvt1);
var callabck2 = new AsyncCallback(OnEvt2);
callabck1.Invoke(new ManualResetResult(null, (ManualResetEvent)waitHandles[0]));
callabck2.Invoke(new ManualResetResult(null, (ManualResetEvent)waitHandles[1]));
WaitHandle.WaitAll(waitHandles);
Console.WriteLine("Finished");
Console.ReadLine();
}
static void OnEvt1(IAsyncResult result)
{
Console.WriteLine("Setting1");
var handle = result.AsyncWaitHandle;
((ManualResetEvent)handle).Set();
}
static void OnEvt2(IAsyncResult result)
{
Thread.Sleep(2000);
Console.WriteLine("Setting2");
var handle = result.AsyncWaitHandle;
((ManualResetEvent)handle).Set();
}
}
public class ManualResetResult : IAsyncResult
{
private object _state;
private ManualResetEvent _handle;
public ManualResetResult(object state, ManualResetEvent handle)
{
_state = state;
_handle = handle;
}
#region IAsyncResult Members
public object AsyncState
{
get { return _state; }
}
public WaitHandle AsyncWaitHandle
{
get { return _handle; }
}
public bool CompletedSynchronously
{
get { throw new NotImplementedException(); }
}
public bool IsCompleted
{
get { throw new NotImplementedException(); }
}
#endregion
}
}
I am not sure I understood your question, but AutoResetEvent.WaitAll seems to solve your problem, if I got it right. It allows you to set more than one handler and it will only be released when all are set.
http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx

Categories