I'm so confused with delegates, my mind is going to eat itself.
I want to connect two different threads to do stuff to one-another.
But obviously, "cross-thread calls are unsafe" exceptions all over the place, demanding I provide delegates instead. I have read countless tutorials, documentations, examples, and I only die a little more inside with each example, because I try it, it just does not work.
Here's my set-up in simplified, code-free way:
I have two threads
.
THREAD1 which has Class DISPLAY_WITH_RICHTEXTBOX
That class has a RICH_TEXT_BOX which I will be editing.
That class has a method int WRITE_TO_TEXTBOX_AND_RETURN_FEEDBACK(string Text)
.
THREAD2 which has Class SOME_CONTROL_PANEL
That class has a TEXT_BOX_OF_DOOM with some text in it
That class has a BUTTON_OF_MAGIC which will call the method from the other class to add the textbox's text to the richtextbox. Upon execution of the method, the method will return back to me an int with the new total size of the Rich text box's text.
.
My problem is, I can't figure out how to make this structure the neatest.
Do I explicitly manipulate the controls VIA a delegate or something, making THREAD2 an upgrade to THREAD1, making it easy to take in/out of the code
Do I call a method to do the editing for me, which would make the THREAD1 class dependent on the THREAD2 class?
And how do I actually build the delegate. Every time I try anything, anywhere, the code complains delegates can only be used with things that are static, but that is HIGHLY impractical for what I'm aiming to create. I can workaround this by making some variables in THREAD1, edit them from THREAD2, and let THREAD1 figure out what to do with the variables, therefore passing all the interactions from THREAD2>THREAD1. But that makes my THREAD1 code so untidy and un-neat I wanna cry.
Is there another way of calling functions from THREAD2 -> THREAD1 that's neat and doesn't involve variables and custom thread-locking-code-of-doom to manage the variables and stuff?
I hope I can be understood what I mean.
.
I just want to have a
THREAD1 > CLASS1 > Rich Text Box
That I can edit with the use of THREAD2 > CLASS2 > Button
So that I don't edit -anything- in THREAD1 > CLASS1
I'm aiming to make that THREAD2 stuff a complete addon to the program, making the dependency only one-way (Thread2 depends on Thread1, without Thread1 expecting it)
If it's impossible to make Thread1 oblivious to Thread2, can I at-least make the Thread1 involvement minimal?
.
Edit: If Delegates and other related stuff is not what am I looking for, WHAT AM I looking for, if I want to get seperate pieces of code to run in their own threads, independent of eachother, but mess with eachother to achieve a greater goal; such as they editing eachother in any way;, so
1. I develop "class MY PROGRAM" to run on its own, later I make an addon
2. "class MY ADDON" which messes with MY PROGRAM however it wants, without needing to go back and edit the MY PROGRAM code to allow communication between the two programs.
Is there a programming language that can achieve this, if C# cannot?
This is what I use on form app to hop between threads and change UI controls
Program.MainForm.Invoke((MethodInvoker)delegate {
//do changes here
});'
Related
sorry if this is a silly question, I am new to C#, so please give me a break.
I am working on Revit API. currently, Revit API doesn't support multi-threading operations.
my question is how to stop a loop without calling a new thread?
I am trying to get a snapshot and I am waiting for the user to pick a snap, so I put an infinite loop till the condition meets
while (!Clipboard.ContainsImage()) //loop till user get a clipboard image
{
}
but what if I want to abort this???
I have tried
private void Abort_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
abort = true;
}
}
but this method requires threading ....any suggestions!!
You want to look into asynchronous processing patterns in Revit - check for instance The Building Coders description of IExternalEvent.
It might take a little while to wrap your head around it, but let me try to explain:
Split your code up into two parts: The first part runs up until the moment you ask the user to pick a snap (I'm assuming this happens in another application?). In a separate thread, poll the clipboard (or register your application as a clipboard viewer) in your while loop. Don't forget to Sleep() while you're polling! As soon as your polling thread finds a picture, create an instance of an IExternalEvent subclass and post it to Revit. When Revit has some spare time, it will execute the Execute method, passing in a UIApplication that you can use to do the rest of your code.
Revit doesn't let you access it's API from multiple threads at the same time, but during the Execute method of an IExternalEvent subclass, you are guaranteed to be in the correct thread for running code.
You can also look into the OnIdling event - basically, this gets called each time Revit has some spare time too. So instead of using a while loop in a separate thread, you could just place your clipboard checking code in the event handler for the OnIdling event and create a mechanism (a flag) to tell you wether you are currently waiting for a snap or not...
I know I'm having a massive derp moment here and this is probably quite easy to actually do - I have had a search around and read a few articles but i'm still struggling a little, so any feedback or pointers to useful resources would be greatly appreciated!
Anyway I have a class called PopulateDatagridViews which I have various functions in, one of which is called ExecuteSqlStatement, this function is simple enough, it initializes an SQL connection and returns a DataTable populated with the results of the SQL query. Within the same class I also have various functions that use string builders to build up SQL statements. (Not ideal, I know.)
I create a PopulateDatagridViews object in my GUI thread and use it to set various datagrid views with with the returned DataTables. For example:
dataGridViewVar.DataSource = populateDgv.GetCustomers();
Naturally a problem I'm having is that the more data to be read from the database, the longer the U.I is unresponsive. I would like to shift the process of retrieving data via the PopulateDatagridViews to a separate thread or BackgroundWorker so as prevent the main GUI thread from locking up whilst this is processed.
I realise I can create a BackgroundWorker to do this and place in the DoWork handler a call to the appropriate function within my PopulateDatagridViews.
I figure I could create a BackgroundWorker for each individual function inside my PopulateDatagridViews class, but surely there is a more efficient way to do this? I'd very much appreciate a point in the right direction on this as it's driving me around the bend!
Additional Info: I use version 4.0 of the .Net framework.
I strongly suggest that you use TPL (Task Parallel Library) http://msdn.microsoft.com/en-us/library/dd537609.aspx
In your case you will create first task to pull some data and than start second task after first is completed to update UI.
I`ll try to find code that i write for similar problem.
Edit: Adding code
Task<return_type> t1 = new Task<return_type>(() =>
{
//do something to take some result
return some_result; //return it
});
t1.Start();
Task t2 = t1.ContinueWith((some_arg_that_represent_previous_task_obj) =>{//ContinueWith guarantees that t2 is started AFTER t1 is executed!
//Update your GUI here
//if you need result from previos task: some_arg_that_represent_previous_task_obj.Result //Your dataset or whatever
}, TaskScheduler.FromCurrentSynchronizationContext()); //VERY important - you must update gui from same thread that created it! (you will have cross thread exeption if you dont add TaskScheduler.FromCurrentSynchronizationContext()
Hope it helps.
Well in that case I recommend reading this msdn article to get some ideas. Afterwards you should look for some tutorials, because the msdn is not the best source to learn things. ;o)
I am a bit new to threading (not new to C#, just haven't done much threading). Can someone explain to me why this does not work?
I have a thread which calls a method I will call "Loop". Loop contains a while loop which will continuously run, and on every loop of the while I want it to check if the A Key is down (using Microsoft's Keyboard class within the XNA Framework). But for some reason it never registers that anything is being pressed.
static Thread thread = new Thread(Loop);
static bool abort = false;
public static void Begin()
{
thread.Start();
}
private static void Loop()
{
while (!abort)
{
if (Keyboard.GetState().IsKeyDown(Keys.A))
Console.WriteLine("A pressed.");
}
}
Might anyone know why the Console.WriteLine() is never being called?
EDIT:
I guess I should explain a little bit. What I am actually trying to do is create something similar to ActionScript's events in C#. So I want to pass a "condition" and an "action" to call if that condition is met in this separate class which contains this thread. What this would do would allow me to just add "event listeners" to objects and it would automatically constantly check if one of the events gets triggered, rather than leave it to me to write If statements in code to check for the events.
Upon trying to do so, the first thing I tested was regarding this XNA Keyboard stuff, because it was one of the reasons I originally wanted to build this system, but it didn't work. So I created the standalone code which i posted above to see if I had made an error in my previous code and it still didn't work.
I never use XNA so I didn't really "know" but I've run into similar situations where you can't get keyboard (and other) input from a worker thread. I googled and found that in XNA this does seem to be the case. See this for example
So you need to (and probably want to) process your game input in the GUI thread. Just checking for input on each update tick should be fine. I doubt even if it did work, you would gain any performance - and you might introduce some interesting synchronization bugs ;-)
It does look like your creating your worker thread properly - this just isn't an application for it.
I'm working on a class library and have opted for a route with my design to make implementation and thread safety slightly easier, however I'm wondering if there might be a better approach.
A brief background is that I have a multi-threaded heuristic algorithm within a class library, that once set-up with a scenario should attempt to solve it. However I obviously want it to be thread safe and if someone makes a change to anything while it is solving for that to causes crashes or errors.
The current approach I've got is if I have a class A, then I create a number InternalA instances for each A instance. The InternalA has many of the important properties from the A class, but is internal an inaccessible outside the library.
The downside of this, is that if I wish to extend the decision making logic (or actually let someone do this outside the library) then it means I need to change the code within the InternalA (or provide some sort of delegate function).
Does this sound like the right approach?
It's hard to really say from just that - but I can say that if you can make everything immutable, your life will be a lot easier. Look at how functional languages approach immutable data structures and collections. The less shared mutable data you have, the simple threading will be.
Why Not?
Create generic class, that accepts 2 members class (eg. Lock/Unlock) - so you could provide
Threadsafe impl (implmenetation can use Monitor.Enter/Exit inside)
System-wide safe impl (using Mutex)
Unsafe, but fast (using empty impl).
another way i have had some success with is by using interfaces to achieve functional separation. the cost of this approach is that you end up with some fields 'repeated' because each interface requires total separation from the others fields.
In my case I had 2 threads that need to pass over a set of data that potentially is large and needs as little garbage collection as possible. Ie I only want to pass change information from the first stage to the second. And then have the first process the next work unit.
this was achieved by the use of change buffers to pass changes from one interface to the next.
this allows one thread to work away at one interface, make all its changes and then publish a struct containing the changes that the other interface (thread) needs to apply prior to its work.
by doing this You have a double buffer ... (thread 1 produces a change report whilst thread 2 consumes the last report). If you add more interfaces (and threads) it appears like there are pulses of work moving through the threads.
This was based on my research and I have no doubt that there are better methods available now.
My aim when coming up with this however was to avoid the need for locks in the vast majority of code by designing out race conditions. the other major consideration is performance in garbage collection - which may not be an issue for you.
this way is all good until you need complex interactions between threads ... then you find that you start forcing the layout of your buffer structures for reuse to get around inheritance which in turn has an upkeep overhead.
A little more information on the problem to help...
The heuristic I'm using is to solve TSP like problems. What happens right at the start of each
calculation is that all the aspects that form the problem (sales man/places to visit) are cloned
so they aren't affected across threads.
This means each thread can change data (such as stock left on a sales man etc) as there are a number
of values that change during the calculation as things progress. What I'd quite like to do is allow
the checked such as HasSufficientStock() for a simple example to be override by a developer using the library.
Unforutantely at present however to add further protection across threads and makings some simplier/lightweight
classes I convert them to these internal classes, and these are the things that are actually used and cloned.
For example
class A
{
public double Stock { get; }
// Processing and cloning actually works using these InternalA's
internal InternalA ConvertToInternal() {}
}
internal class InternalA : ICloneable
{
public double Stock { get; set; }
public bool HasSufficientStock() {}
}
OK, please disregard what has gone before. I'm not getting the errors anymore, so it seems my problem is with getting a Chart to update when I change the values to which the Chart is data bound.
//Disregard below here
Hi all. I have a WinForms application that has a panel, panel1. A background thread creates some other controls that then get added to panel1 like so
panel1.Controls.AddRange(myArrayOfControls);
This works great and I can see my controls get added. But, when new data comes in on another thread, I update values in the controls' parent objects and then need to Refresh() to get the display to update with the new values. Calling Refresh() in either context, the thread where the data comes in or the objects that receive the updated data causes an InvalidOperation exception because Invoke is required. I've tried using Invoke in my model objects and also the thread where the data is incoming and can't seem to shake the error.
If anyone has some guidance I'd greatly appreciate it.
UPDATE: Here's a little more info. I didn't think it would require it, but I was wrong. :)
I have an object class MyObject. This MyObject class gets created in a thread called topologyThread. Data comes in on dataThread. Instances of MyObject have a Panel instance variable and the Panel has child Controls including two Charts from the System.Windows.Forms.DataVisualization.Charting namespace. So, as data comes in on dataThread, I update the respective data values in the MyObject objects and then need to refresh the Charts to show the updated data.
I do know the data is processing fine. In my MyObject class, I'm logging the new values to Console in the setter for the property and see the new values show up.
You must do both operations (refresh and updating of control's parent object) from the main UI thread. If you are modifying a control from a background thread and not getting an exception that is bad luck because it is definitely an error.
The best way to do this is to use
theControl.Invoke(new MethodInvoker(MyUpdateMethod));
If you have a sample of how the update is done, we can give a better sample on how to properly call it from the background thread.
JaredPar is a pretty good answer. I would like to add to it a bit as to the reason your code sort of works.
With windows forms you can talk to the UI thread from other threads. This is really bad practice in all cases.
The catch is that when you do it, it is hard to catch because sometimes the UI will work as if nothing is wrong. item will get added or changed and the UI will reflect the changes. However other times running the same exact code, it will not work.
That is the catch with touching the UI from any thread other then the UI thread. The out come is inconsistent and that is why is very bad practice.
God I wish I could comment. :)
JaredPar's answer is good. It can cause problems in some instances (notably when the method is invoked before the form is finished being constructed). Here's a somewhat more robust implementation (using extension methods)
public static class ControlInvokeExtensions
{
public static void InvokeOnHostThread(Control host, MethodInvoker method)
{
if (IsHandleCreated)
Invoke(new EventHandler(delegate { method(); }));
else
method();
}
}
now you can call it this way
panel1.InvokeOnHostThread(() => panel1.Controls.AddRange(myArrayOfControls));
or if you're in the form:
InvokeOnHostThread(() => panel1.Controls.AddRange(myArrayOfControls));