I will try and keep this short and sweet.
I have this code which is a result of a button being pressed (so its on the main UI thread)
MessageCenter.Init();
the above method does this (as well as other things)
NS = NSTimer.CreateRepeatingScheduledTimer(TimeSpan.Parse("00:00:30"), delegate
{
NSObject.InvokeInBackground(() =>
{
HandleElapsed();
});
});
HandleElapsed(); obtains an exclusive lock on an object using the Monitor.Enter(obj) method. mean while the main ui thread also may need to obtain an exclusive lock. (the lock is in place to ensure sqlite data integrity)
when the main UI encounters a lock on the object (i.e its already locked) the entire app just halts (including the background thread)
I should mention the UI may need to get a lock when its told to change its content. HandleElapsed(); will ask the main UI thread to change its content.
NSNotificationCenter.DefaultCenter.PostNotificationName("ChangeDetail", new NSString("News"));
please note the change in contents is completed on the main thread
UIApplication.SharedApplication.InvokeOnMainThread();
its seems when the main ui is stuck on a lock... its also doesn't allow the background thread to continue thus the background thread is not able to move on a call to Monitor.Exit();
am i missing something?
Solved it.
I kept the database open throughout. and simply applied the locking mechanism
lock(SQLight.Connection)
{
...
}
this means all my threads uses the same connection but each thread can only interact with the data in turn.
This seems to have achieved what I wanted
In the book Programming C#, it has some sample code about SynchronizationContext:
SynchronizationContext originalContext = SynchronizationContext.Current;
ThreadPool.QueueUserWorkItem(delegate {
string text = File.ReadAllText(#"c:\temp\log.txt");
originalContext.Post(delegate {
myTextBox.Text = text;
}, null);
});
I'm a beginner in threads, so please answer in detail.
First, I don't know what does context mean, what does the program save in the originalContext? And when the Post method is fired, what will the UI thread do?
If I ask some silly things, please correct me, thanks!
EDIT: For example, what if I just write myTextBox.Text = text; in the method, what's the difference?
What does SynchronizationContext do?
Simply put, SynchronizationContext represents a location "where" code might be executed. Delegates that are passed to its Send or Post method will then be invoked in that location. (Post is the non-blocking / asynchronous version of Send.)
Every thread can have a SynchronizationContext instance associated with it. The running thread can be associated with a synchronization context by calling the static SynchronizationContext.SetSynchronizationContext method, and the current context of the running thread can be queried via the SynchronizationContext.Current property.
Despite what I just wrote (each thread having an associated synchronization context), a SynchronizationContext does not necessarily represent a specific thread; it can also forward invocation of the delegates passed to it to any of several threads (e.g. to a ThreadPool worker thread), or (at least in theory) to a specific CPU core, or even to another network host. Where your delegates end up running is dependent on the type of SynchronizationContext used.
Windows Forms will install a WindowsFormsSynchronizationContext on the thread on which the first form is created. (This thread is commonly called "the UI thread".) This type of synchronization context invokes the delegates passed to it on exactly that thread. This is very useful since Windows Forms, like many other UI frameworks, only permits manipulation of controls on the same thread on which they were created.
What if I just write myTextBox.Text = text; in the method, what's the difference?
The code that you've passed to ThreadPool.QueueUserWorkItem will be run on a thread pool worker thread. That is, it will not execute on the thread on which your myTextBox was created, so Windows Forms will sooner or later (especially in Release builds) throw an exception, telling you that you may not access myTextBox from across another thread.
This is why you have to somehow "switch back" from the worker thread to the "UI thread" (where myTextBox was created) before that particular assignment. This is done as follows:
While you are still on the UI thread, capture Windows Forms' SynchronizationContext there, and store a reference to it in a variable (originalContext) for later use. You must query SynchronizationContext.Current at this point; if you queried it inside the code passed to ThreadPool.QueueUserWorkItem, you might get whatever synchronization context is associated with the thread pool's worker thread. Once you have stored a reference to Windows Forms' context, you can use it anywhere and at any time to "send" code to the UI thread.
Whenever you need to manipulate a UI element (but are not, or might not be, on the UI thread anymore), access Windows Forms' synchronization context via originalContext, and hand off the code that will manipulate the UI to either Send or Post.
Final remarks and hints:
What synchronization contexts won't do for you is telling you which code must run in a specific location / context, and which code can just be executed normally, without passing it to a SynchronizationContext. In order to decide that, you must know the rules and requirements of the framework you're programming against — Windows Forms in this case.
So remember this simple rule for Windows Forms: DO NOT access controls or forms from a thread other than the one that created them. If you must do this, use the SynchronizationContext mechanism as described above, or Control.BeginInvoke (which is a Windows Forms-specific way of doing exactly the same thing).
If you're programming against .NET 4.5 or later, you can make your life much easier by converting your code that explicitly uses SynchronizationContext, ThreadPool.QueueUserWorkItem, control.BeginInvoke, etc. over to the new async / await keywords and the Task Parallel Library (TPL), i.e. the API surrounding the Task and Task<TResult> classes. These will, to a very high degree, take care of capturing the UI thread's synchronization context, starting an asynchronous operation, then getting back onto the UI thread so you can process the operation's result.
I'd like to add to other answers, SynchronizationContext.Post just queues a callback for later execution on the target thread (normally during the next cycle of the target thread's message loop), and then execution continues on the calling thread. On the other hand, SynchronizationContext.Send tries to execute the callback on the target thread immediately, which blocks the calling thread and may result in deadlock. In both cases, there is a possibility for code reentrancy (entering a class method on the same thread of execution before the previous call to the same method has returned).
If you're familiar with Win32 programming model, a very close analogy would be PostMessage and SendMessage APIs, which you can call to dispatch a message from a thread different from the target window's one.
Here is a very good explanation of what synchronization contexts are:
It's All About the SynchronizationContext.
It stores the synchronization provider, a class derived from SynchronizationContext. In this case that will probably be an instance of WindowsFormsSynchronizationContext. That class uses the Control.Invoke() and Control.BeginInvoke() methods to implement the Send() and Post() methods. Or it can be DispatcherSynchronizationContext, it uses Dispatcher.Invoke() and BeginInvoke(). In a Winforms or WPF app, that provider is automatically installed as soon as you create a window.
When you run code on another thread, like the thread-pool thread used in the snippet, then you have to be careful that you don't directly use objects that are thread-unsafe. Like any user interface object, you must update the TextBox.Text property from the thread that created the TextBox. The Post() method ensures that the delegate target runs on that thread.
Beware that this snippet is a bit dangerous, it will only work correctly when you call it from the UI thread. SynchronizationContext.Current has different values in different threads. Only the UI thread has a usable value. And is the reason the code had to copy it. A more readable and safer way to do it, in a Winforms app:
ThreadPool.QueueUserWorkItem(delegate {
string text = File.ReadAllText(#"c:\temp\log.txt");
myTextBox.BeginInvoke(new Action(() => {
myTextBox.Text = text;
}));
});
Which has the advantage that it works when called from any thread. The advantage of using SynchronizationContext.Current is that it still works whether the code is used in Winforms or WPF, it matters in a library. This is certainly not a good example of such code, you always know what kind of TextBox you have here so you always know whether to use Control.BeginInvoke or Dispatcher.BeginInvoke. Actually using SynchronizationContext.Current is not that common.
The book is trying to teach you about threading, so using this flawed example is okayish. In real life, in the few cases where you might consider using SynchronizationContext.Current, you'd still leave it up to C#'s async/await keywords or TaskScheduler.FromCurrentSynchronizationContext() to do it for you. But do note that they still misbehave the way the snippet does when you use them on the wrong thread, for the exact same reason. A very common question around here, the extra level of abstraction is useful but makes it harder to figure out why they don't work correctly. Hopefully the book also tells you when not to use it :)
The purpose of the synchronization context here is to make sure that myTextbox.Text = text; gets called on the main UI thread.
Windows requires that GUI controls be accessed only by the thread they were created with. If you try assign the text in a background thread without first synchronizing (through any of several means, such as this or the Invoke pattern) then an exception will be thrown.
What this does is save the synchronization context prior to creating the background thread, then the background thread uses the context.Post method execute the GUI code.
Yes, the code you've shown is basically useless. Why create a background thread, only to immediately need to go back to the main UI thread? It's just an example.
SynchronizationContext basically is a provider of callback delegates' execution. It is responsible for ensuring that the delegates are run in a given execution context after a particular portion of code (encapsulated inside a Task object in .Net TPL) in a program has completed its execution.
From technical point of view, SC is a simple C# class that is oriented to support and provide its function specifically for Task Parallel Library objects.
Every .Net application except for console applications has a tailored implementation of this class based on the specific underlying framework, eg: WPF, WindowsForm, Asp Net, Silverlight, etc.
The importance of this object is bound to the synchronization between results returning from asynchronous execution of code, and the execution of dependent code that is waiting for results from that asynchronous work.
And the word "context" stands for execution context. That is, the current execution context where that waiting code will be executed- namely the synchronization between async code and its waiting code happens in a specific execution context. Thus this object is named SynchronizationContext.
It represents the execution context that will look after syncronization of async code and waiting code execution.
To the Source
Every thread has a context associated with it -- this is also known as the "current" context -- and these contexts can be shared across threads. The ExecutionContext contains relevant metadata of the current environment or context in which the program is in execution. The SynchronizationContext represents an abstraction -- it denotes the location where your application's code is executed.
A SynchronizationContext enables you to queue a task onto another context. Note that every thread can have its own SynchronizatonContext.
For example: Suppose you have two threads, Thread1 and Thread2. Say, Thread1 is doing some work, and then Thread1 wishes to execute code on Thread2. One possible way to do it is to ask Thread2 for its SynchronizationContext object, give it to Thread1, and then Thread1 can call SynchronizationContext.Send to execute the code on Thread2.
SynchronizationContext provides us a way to update a UI from a different thread (synchronously via the Send method or asynchronously via the Post method).
Take a look at the following example:
private void SynchronizationContext SyncContext = SynchronizationContext.Current;
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(Work1);
thread.Start(SyncContext);
}
private void Work1(object state)
{
SynchronizationContext syncContext = state as SynchronizationContext;
syncContext.Post(UpdateTextBox, syncContext);
}
private void UpdateTextBox(object state)
{
Thread.Sleep(1000);
string text = File.ReadAllText(#"c:\temp\log.txt");
myTextBox.Text = text;
}
SynchronizationContext.Current will return the UI thread's sync context. How do I know this? At the start of every form or WPF app, the context will be set on the UI thread. If you create a WPF app and run my example, you'll see that when you click the button, it sleeps for roughly 1 second, then it will show the file's content. You might expect it won't because the caller of UpdateTextBox method (which is Work1) is a method passed to a Thread, therefore it should sleep that thread not the main UI thread, NOPE! Even though Work1 method is passed to a thread, notice that it also accepts an object which is the SyncContext. If you look at it, you'll see that the UpdateTextBox method is executed through the syncContext.Post method and not the Work1 method. Take a look at the following:
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread.Sleep(1000);
string text = File.ReadAllText(#"c:\temp\log.txt");
myTextBox.Text = text;
}
The last example and this one executes the same. Both doesn't block the UI while it does it jobs.
In conclusion, think of SynchronizationContext as a thread. It's not a thread, it defines a thread (Note that not all thread has a SyncContext). Whenever we call the Post or Send method on it to update a UI, it's just like updating the UI normally from the main UI thread. If, for some reasons, you need to update the UI from a different thread, make sure that thread has the main UI thread's SyncContext and just call the Send or Post method on it with the method that you want to execute and you're all set.
Hope this helps you, mate!
This example is from Linqpad examples from Joseph Albahari but it really helps in understanding what Synchronization context does.
void WaitForTwoSecondsAsync (Action continuation)
{
continuation.Dump();
var syncContext = AsyncOperationManager.SynchronizationContext;
new Timer (_ => syncContext.Post (o => continuation(), _)).Change (2000, -1);
}
void Main()
{
Util.CreateSynchronizationContext();
("Waiting on thread " + Thread.CurrentThread.ManagedThreadId).Dump();
for (int i = 0; i < 10; i++)
WaitForTwoSecondsAsync (() => ("Done on thread " + Thread.CurrentThread.ManagedThreadId).Dump());
}
I'm developing a WinForms application with SQL Compact as main database. I was told i would NEVER mess with the UI Thread, every operation needs to be done outside the UI Thread.. going by this speech for every CRUD operation I create a thread and a progress bar appears, but I think this might not be the best way to do this, and I'm quite unsure of where and when to use threads along side with database operations. I'm not using the UI Thread to make these DB calls but i'm not seeing any problems if i would. To show the information to the user i make Invokes when needed (to show data on a grid or a combobox). Here is a small piece of code:
this.SuspendLayout();
ProgressDialog progressDialog = new ProgressDialog();
Thread backgroundThread = new Thread(
new ThreadStart(() =>
{
var unitOfWork = new DAL.Implementations.Entity_Framework.UnitOfWork<dbgmEntities>();
var espacosRepository = unitOfWork.GetRepository<DAL.Espacos>();
Espacos espaco;
if (e.Row.Cells["ESP_Descr"].Value != null)
espaco = new Espacos { ESP_Nome = e.Row.Cells["ESP_Nome"].Value.ToString(), ESP_Descr = e.Row.Cells["ESP_Descr"].Value.ToString() };
else
espaco = new Espacos { ESP_Nome = e.Row.Cells["ESP_Nome"].Value.ToString() };
espacosRepository.AddOrAttach(espaco);
unitOfWork.Save();
}
));
backgroundThread.Start();
progressDialog.Show();
progressDialog.Close();
this.ResumeLayout();
I'm using Repository Pattern with SQL Compact and Entity Framework 4.0, as you can see i do database operations inside threads and not on the UI Thread which would block the user interface if it was a heavy operation.. the question is:
Is it really necessary to make database calls from a thread outside the UI Thread or just a heavy operation? Like adding more than 1 or 2 rows on different tables.
Thanks
The UI thread really should just be used to display things to the user and process input events from the user. Anything else should be delgated to a worker thread. That includes database operations. The issue is that long-running processes tie up the main thread so that it is unable to do anything else for the duration of the process. Since it's hard to guarantee that your database operation is going to come back quickly, it's probably not a good idea to have operations that access it be on the main thread.
Keep in mind that this is just a guideline. If whatever work you're performing takes a very small amount of time, it's not worth it to spin up a new thread. Spinning up a new thread costs you CPU cycles as well, so it might not be worth it to do that work on another thread.
Some recommendations:
Don't instantiate threads directly; use the thread pool instead: ThreadPool.QueueUserWorkItem
Don't immediately close your progress bar. Show it, and then invoke the call to hide it from the worker thread after your database operation is complete.
This is a good article on the thread pool.
As Dan said, the UI thread should be used simply for displaying things and getting user input.
However, the vast majority of operations we tend to do are extremely fast. To the point that spinning up another thread adds more to the time cost than simply performing the operation itself. My suggestion is that you only spin up a new thread for anything which will take more than a few seconds to process.
I've been researching on how to do this for about a week and I'm still not sure about the correct approach, in some examples I see the Thread class is used in others I see Invoke is used which has confused me a bid.
I have a GUI program in c# which contains a textBox which will be used to give information to the user.
The problem I'm facing is that I'm not sure how I can append text to textBox from another class which is running on another thread. If someone can show me a working example, it would help me greatly.
Best Regards!
Easy:
MainWindow.myInstance.Dispatcher.BeginInvoke(new Action(delegate() {MainWindow.myInstance.myTextBox.Text = "some text";});
WHERE MainWindow.myInstance is a public static variable set to the an instance of MainWindow (should be set in the constructor and will be null until an instance is constructed).
Ok thats a lot in one line let me go over it:
When you want to update a UI control you, as you say, have to do it from the UI thread. There is built in way to pass a delegate (a method) to the UI thread: the Dispatcher. I used MainWindow.myInstance which (as all UI components) contains reference to the Dispatcher - you could alternatively save a reference to the Dispatcher in your own variable:
Dispatcher uiDispatcher = MainWindow.myInstance.Dispatcher;
Once you have the Dispatcher you can either Invoke() of BeginInvoke() passing a delegate to be run on the UI thread. The only difference is Invoke() will only return once the delegate has been run (i.e. in your case the TextBox's Text has been set) whereas BeginInvoke() will return immediately so your other thread you are calling from can continue (the Dispatcher will run your delegate soon as it can which will probably be straight away anyway).
I passed an anonymous delegate above:
delegate() {myTextBox.Text = "some text";}
The bit between the {} is the method block. This is called anonymous because only one is created and it doesnt have a name - but I could instantiated a delegate:
Action myDelegate = new Action(UpdateTextMethod);
void UpdateTextMethod()
{
myTextBox.Text = "new text";
}
Then passed that:
uiDispatcher.Invoke(myDelegate);
I also used the Action class which is a built in delegate but you could have created your own - you can read up more about delegates on MSDN as this is going a bit off topic..
Sounds like you're using a background thread for processing, but want to keep the UI responsive? The BackgroundWorker sounds like the ticket:
The BackgroundWorker class allows you
to run an operation on a separate,
dedicated thread. Time-consuming
operations like downloads and database
transactions can cause your user
interface (UI) to seem as though it
has stopped responding while they are
running. When you want a responsive UI
and you are faced with long delays
associated with such operations, the
BackgroundWorker class provides a
convenient solution.
Just use BackgroundWorker for the same. It is simple and takes away the pain of managing threads of your own. for more, you can see: http://dotnetperls.com/backgroundworker
What do I want to achieve: I want to perform some time consuming operations from my MDI winforms application (C# - .NET).
An MDI child form may create the thread with the operation, which may take long time (from 0.1 seconds, to even half hour) to complete. In the meantime I want the UI to respond to user actions, including manipulation of data in some other MDI child form. When the operation completes, the thread should notify the MDI child that the calculations are done,
so that the MDI child can perform the post-processing.
How can I achieve this:
Should I use explicit threading (i.e., create explicit threads), thread pools? Or simply just propose your solution. Should I create foreground or background threads?
And how does the thread communicates with the GUI, according the solution you propose?
If you know of a working example that handles a similar situation, please make a note.
I think you are looking for the BackgroundWorker class. Example
Use the BackgroundWorker class. It does just what you're looking for:
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += new DoWorkEventHandler(LongRunningCode);
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CallbackOnCompletion);
backgroundWorker.RunWorkerAsync();
Also, to update your UI from the background thread, you need to call Invoke on your UI element.
This depends, slightly.
In general, I agree with BFree that the BackgroundWorker is likely the best option here. I makes notification back to the UI simple, etc.
That being said, the only reason I'm posting, and questioning whether you may want to use BackgroundWorker is this statement:
which may take long time (from 0.1 seconds, to even half hour) to complete
BackgroundWorker uses a ThreadPool thread to perform its processing. This means that closing your Application form will terminate the thread, since it's a background thread.
If your "half hour" processing "work" is something that you would like to have continue operating, even if the form is closed, you may want to make your own foreground thread to perform this operation, and handle the UI marshaling yourself.
While the BackgroundWorker object is an obvious choice, it may not be advisable for a lengthy process, as it uses the ThreadPool. The conventional wisdom around the ThreadPool is that it shouldn't be used for long-running tasks; in these cases explicit thread creation is advisable.
You can still interact with the GUI by calling Invoke or BeginInvoke on the form (or any of its controls), passing in a delegate that will perform the GUI-related actions.
If you have a very finite number of threads (let's say, at most 4), then you can create them yourself. If you need them to be managed in a way that you don't want to deal with it, then a threadpool is one option or .NET 4.0's System.Threading.Tasks namespace.
You'll probably need to use delegates. Here's an example of one that writes to the UI and one that reads from the UI:
delegate void SetResultsTextCallback(string text);
delegate string GetIterationCountCallback();
private void SetResultsText(string text)
{
if (this.ResultsBox.InvokeRequired)
{
var d = new SetResultsTextCallback(SetResultsText);
this.Invoke(d, new object[] { text });
}
else
{
this.ResultsBox.Text = text;
}
}
private string GetIterationCount()
{
if (this.RepetitionSelector.InvokeRequired)
{
var del = new GetIterationCountCallback(GetIterationCount);
IAsyncResult result = del.BeginInvoke(null, null);
return del.EndInvoke(result);
}
else
{
return RepetitionSelector.SelectedItem.ToString();
}
}
In this example, ResultsBox is a TextBox and RepetitionSelector is a combobox.
You have many options:
Use BackgroundWorker directly which basically does most of the work for you, but the lengthy operation must be known by the UI.
Inherit from System.ComponentModel.BackgroundWorker which enables to use the operation as a component and separate the logic from the UI.
Use the Event-based pattern, which would allow greater control for the parameters and events raised.
Use the delegates, if there is really nothing to report but the ned of the operation. You must have caution as the callback method is not guaranteed to run in the UI thread.
I recommend creating a thread and using a callback method to communicate with the UI.
I give an example in this solution, where you'll also find examples for other approaches: .NET Threading & Locks & Waiting.