In my solution I have three projects: Application, Class Library providing data and Windows Runtime Component for background task. Problem is, I need bot application and background task to use data provider. And this ends with "The application called an interface that was marshalled for a different thread". Dispatcher isn't quite a solution as I can't retrun something while in dispatcher.
Background Task is called rarely, so is it possible to unmarshall data providing interface for a second so background task could get its data? If it is - how to do that, if it isn't - what else can I do?
You have two options:
Ensure that calls from the background thread are marshalled to the appropriate thread using a wrapper class. Typically this will mean writing a class that takes the original object as a parameter, replicates its class interface in it's own structure but checks for access before calling the methods directly.
Create a new data adaptor that can be called on the background thread.
Either of these options will solve your issue.
Related
Background
I faced this problem a couple of years ago and got this very helpful answer from Stephen Cleary. Problem with VSTO add-ins is that they do not set a SynchronizationContext and therefore async calls do not resume on UI thread, causing all sorts of cross-thread access troubles. The solution, as he mentioned is to manually call SetSynchronizationContext before calling any async function.
I have been using this technique since then and thought that was all there was to it. But today I have seen a situation where even manually setting the context does not force it to resume on calling thread.
Situation
My VSTO add-in contains a WPF pane (inside a CustomTaskPane) which is bound to its ViewModel that contains several AsyncRelayCommand properties (from WCT). One of these commands calls my Data Service which in turn calls a RestSharp methods to fetch data from the API server.
All these calls use async/await and all these call use ConfigureAwait(false) except the one at the top level (i.e. the command itself). Here is a snapshot of how this call-site looks like:
As you can see, I have manually called SetSynchronizationContext before doing the await call. It also shows that SynchronizationContext.Current is set after it resumes after the await call, but somehow the code is still running on the worker thread. I also verified that the code was running on UI thread when it hit line 259 before drilling down into the await call.
I have already spent a lot of time and effort on this and can't make any sense of it. Can anyone help me figure out if I'm missing something obvious?
You need to use an instance of the WindowsFormsSynchronizationContext class instead.
The WindowsFormsSynchronizationContext class provides a synchronization mechanism for Windows Forms.
The DispatcherSynchronizationContext class is for WPF applications which uses two threads. One thread is background thread for rendering and the other thread is for UI. So, UI elements in one thread are not accessible to other UI threads. Microsoft introduced the dispatcher which is responsible for multiple UI threads interaction.
I have the following situation.
Multiple forms that display information stored in a shared object. A background worker thread that is constantly updating the shared object.
I thought about having the shared object be something like a singleton but I am worried about the multi threading concerns.
What is the best way to solve this kind of problem?
I was asked what is the problem but I thought I covered that but I will try to add more detail.
Ok I have one lets say an object like this
public class Connections
{
public List<User> Users {get;set;}
public List<Computer> Computers {get;set;}
}
Then I have 2 different forms that are open at the same time. One form is for displaying the Users, the other is for displaying the Computers.
Next I have a background thread that is populating the Users and Computers.
How can I share the data that the background thread is building with multiple forms?
Any data shared between the background thread and the UI thread needs to be protected by locks. That is, you need to pick an object to synchronize on (possibly the "main object" that's being shared, if there is one), and anytime you modify or read a member variable from that object, you need to first lock on it.
Alternatively, you could use Control.Invoke() from the background thread anytime you need to update data so that only the UI thread will actually modify the shared object, making it effectively no longer shared between threads.
A simple and clean way to solve this problem is by using Tasks (System.Threading.Tasks) instead of a BackgroundWorker. Pass in a SyncronizationContext created on a UI thread and the framework does all the locking work for you.
This might be a very naive question:
I'm trying to create a client application that uses ZeroMQ for communicating to multiple servers. The client would like to send a large number of requests to these servers and get responses to them (so req-rep pattern).
The issue I'm facing is that ZeroMQ sockets should only be used in the threads they are created on.
One way is to invoke each of the requests in a new task: inside the task, create a connection, send request and get response. However, the connection setup is very expensive.
A second way might be to have the connection open to servers in different threads; then somehow invoke the sending routine in the same context as the thread and get results. Is there a way in C# to call a function on thread X from thread Y, but execute it in the context of thread X and then get a return value?
I understand this might be a bad approach. What is the best way to achieve what I want without much overhead?
The typical means of handling this type of scenario is to setup a SynchronizationContext. This class is intended for exactly that type of scenario, though the most common examples revolve around the UI thread.
You can use SynchronizationContext.Post to asynchronously post a "message" to that context (thread) which will receive a callback upon completion. This can be simplified with the TPL, which specifically allows you to create a TaskScheduler from a SynchronizationContext, which in turn will allow you to schedule a Task to run on a custom context.
With C# 5, this becomes incredibly useful, as you can then use async/await to synchronize your calls and push work to/from these "threads".
For an implementation example, see the ActionDispatcherSynchronizationContext within the Nito Asynchronous Library.
I'm trying to interact with a third party application but whenever I try and call a method, I get an error message saying System.InvalidOperationException: Operation must be performed on the application thread. The exception is of type System.Reflection.TargetInvocationException and I'm guessing this is because my app is running in a completely separate process. Is there a way to get my program, which is a console application, to start running on the same thread as the third party app?
You can't get two separate applications to run in a single thread.
If you are trying to interact with some UI controls in your application, you can use .Invoke() to make sure the relevant code is executed in the UI thread.
If you're trying to manipulate the a third party application, the appropriate solution depends entirely on how you're interacting with it. Does it provide an API? Sending messages to its window handle? ??
In order to interact with a running instance of another application, you'll need to use something like remoting (obsolete) or WCF. Essentially, the other application acts as a server, and you have to somehow connect to it. Referencing its assembly, instantiating one of the classes therein defined and calling methods on that instance won't let you talk to an already-executing process.
I need to write an application in c# that keeps track of multiple tasks, each being implemented as a class instance running on its own thread. A user interface will be used to display the status of each task instance depending on which task I select from tree view which will display the list of tasks.
An idea I have is to create some other class, called PropertyClass which will have an instance of the TaskClass and some properties relating to this TaskClass instance. Then whenever the TaskClass instance changes its state the related property in the PropertyClass instance will get updated and then the UI will be updated with these property values from the PropertyClass when the task is selected from the Tree View list.
There will probably be hundreds of these tasks running which will be communicating with a service on a remote machine.
How else can I go about coding this solution in an efficient way?
Read this document from the MSDN on the Task Parallel Library first.
I have a few suggestions.
First, you need a way to make sure you don't end up with threads blocking your app from closing. One sure fire way to do this is to make sure all your threads are background threads. That can be a little problematic if you have to make sure a thread's work is done before it is joined or aborted.
Second, you could look at using the ThreadPool class which should make creating and using threads more efficient. The thread pool is there to help you manage your threads.
Third, you will need a method of synchronizing your data access from the GUI to data in the other threads. In WPF you use the Dispatcher and in WinForms you'll use Invoke.
Forth, the BackgroundWorker class can help with all of these if it'll fit in the model of your application.
Fifth, events and delegates can be BeginInvoked which essentially puts them on another thread. It's kind of implicit multi-threading and can be useful.
Sixth, and I've not yet had the chance to use this, .Net 4 has the Parallel Task Library that may be of use to you.
Seventh, safe shared data access and synchronization can be accomplished using lock and/or Monitor.
Hope this helps.
-Nate
If each TaskClass instance corresponds to a node on the tree view, you can store the TaskClass instance in the tree view item's Tag property. Or you could create a dictionary of TaskClasses, keyed by a unique identifier such as a GUID, and store the identifier in the Tag property.
In either case, use a callback method to signal that a TaskClass instance has an update.