Process a call in wpf Application in Main thread - c#

My wpf application connects to my legacy application through communication pipes. WPF application allows user to plot locations on map using a button on the interface. So when user clicks the button on WPF application user interface, a pipe message is sent to legacy application to allow user to plot locations on map. When user plot locations on map using mouse, the coordinates are sent back to wpf application using the 2 way communication pipe. When my wpf application receives the coordinates, it needs to process and perform the workflows accordingly. There might appear some errors, so application might need to show error message. or in some cases might need to clear collections that were created in Application main thread. So there is a whole branch of code that get executed when coordinates are received.
How can I bring my WPF application back to Main thread so that when coordinates are received, user actions like showing message box etc.. can be performed?
right now I am getting exceptions like "collection was created in a different thread".
I know I can use this code to show message in Main thread or clear collections
Application.Current.Dispatcher.Invoke((Action)(() => { PointsCollection.Clear(); }));
Application.Current.Dispatcher.Invoke((Action)(() => { MessageBox.Show("Error"); }));
but this wont work in unit testing and also I will have to do this in lot of places. is there a better way?
public void PipeClientMessageReceived(int type, string message)
{
var command = (PipeCommand)type;
switch (command)
{
case PipeCommand.Points:
{
string[] tokens = message.Split(':');
var x = Convert.ToDouble(tokens[0]);
var y = Convert.ToDouble(tokens[1]);
SetSlotCoordinates(new Point2D(x, y));
}
break;
}
}
SetSlotCoordinates method actually does all the work to process the coordinates. I tried putting this calling in Application.Current.Dispatcher but no success.
Application.Current.Dispatcher.Invoke((Action)(() => { SetSlotCoordinates(new Point2D(x, y)); }));

Unfortunately, the question is not very clear. What issue exists with unit testing that you believe prevents you from using Dispatcher.Invoke()? When you tried using Dispatcer.Invoke() on the call to SetSlotCoordinates(), in what way was there "no success"?
Basically, the use of Dispatcher.Invoke() (or its asynchronous sibling, Dispatcher.BeginInvoke() should do the job for you. However, if you're able, I would recommend using the new async/await pattern.
Without a complete code example, it's impossible to give you the exact code. But it would look something like this:
async Task ReceiveFromPipe(Stream pipeStream, int bufferSize)
{
byte[] buffer = new byte[bufferSize];
int byteCount;
while ((byteCount = await pipeStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
int type;
string message;
if (TryCompleteMessage(buffer, byteCount, out type, out message))
{
PipeClientMessageReceived(type, message);
}
}
}
Using this technique, and assuming that the ReceiveFromPipe() method is called from the UI thread, you will already be on the UI thread when the read from the pipe completes, making everything else "just work".
Note: I've glossed over details such as how exactly you maintain your buffer of incoming data until a complete message is received...I've assumed that's encapsulated in the hypothetical TryCompleteMessage() method. The above is for illustration purposes, and of course you'd have to adapt to your own specific code.
Also, you may find it makes more sense to do more of the processing in the background thread, in which case you'd put the actual receive and that processing into a separate async method; in that case, that method would still call ReadAsync(), but you could call ConfigureAwait(false) on the return value of that, so that the switch back to the UI thread didn't happen until that separate async method returned. For example:
async Task ReceiveFromPipe(Stream pipeStream, int bufferSize)
{
Action action;
while ((action = await ReceivePoint2D(pipeStream, bufferSize)) != null)
{
action();
}
}
async Task<Action> ReceivePoint2D(Stream pipeStream, int bufferSize)
{
byte[] buffer = new byte[bufferSize];
int byteCount;
while ((byteCount = await pipeStream
.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
{
int type;
string message;
if (TryCompleteMessage(buffer, byteCount, out type, out message))
{
return PipeClientMessageReceived(type, message);
}
}
return null;
}
public Action PipeClientMessageReceived(int type, string message)
{
var command = (PipeCommand)type;
switch (command)
{
case PipeCommand.Points:
{
string[] tokens = message.Split(':');
var x = Convert.ToDouble(tokens[0]);
var y = Convert.ToDouble(tokens[1]);
return () => SetSlotCoordinates(new Point2D(x, y));
}
break;
}
}
In the above example, the asynchronous code does everything except the call to SetSlotCoordinates(). For that, it wraps the call in an Action delegate, returning that to the UI thread where the UI thread can then invoke it. Of course, you don't have to return an Action delegate; that was just the most convenient way I saw to adapt the code you already have. You can return any value or object and let the UI thread handle it appropriately.
Finally, with respect to all of the above, note that nowhere in the code is an explicit dependency on the UI thread. While I'm not sure what issue you are concerned with respect to unit testing, the above should be much more easily adapted to unit testing scenarios where no Dispatcher is available or you'd prefer not to use it for some reason.
If you want to stick with explicit use of Dispatcher, then you should be more specific about what exactly isn't working.

Related

Alternative in a situation of recurring Task demand

I have observer module which takes care of subscriptions of some reactive stream I have created from Kafka. Sadly I need to Poll in order to receive messages from kafka, so I need to dedicate one background thread for that. My first solution was this one:
public void Poll()
{
if (Interlocked.Exchange(ref _state, POLLING) == NOTPOLLING)
{
Task.Run(() =>
{
while (CurrentSubscriptions.Count != 0)
{
_consumer.Poll(TimeSpan.FromSeconds(1));
}
_state = NOTPOLLING;
});
}
}
Now my reviewer suggested that I should Task because it have statuses and can be checked if they are running or not. This led to this code:
public void Poll()
{
// checks for statuses: WaitingForActivation, WaitingToRun, Running
if (_runningStatuses.Contains(_pollingTask.Status)) return;
_pollingTask.Start(); // this obviously throws exception once Task already completes and then I want to start it again
}
Task remained pretty much the same but check changed, now since my logic is that I want to start polling when I have subscriptions and stop when I don't I need to sort of re-use the Task, but since I can't I am wondering do I need to go back to my first implementation or is there any other neat way of doing this that right now I am missing?
I am wondering do I need to go back to my first implementation or is there any other neat way of doing this that right now I am missing?
Your first implementation looks fine. You might use a ManualResetEventSlim instead of enum and Interlocked.Exchange, but that's essentially the same... as long as you have just two states.
I think I made a compromise and removed Interlocked API for MethodImpl(MethodImpl.Options.Synchronized) it lets me have simple method body without possibly confusing Interlocked API code for eventual newcomer/inexperienced guy.
[MethodImpl(MethodImplOptions.Synchronized)]
public void Poll()
{
if (!_polling)
{
_polling = true;
new Task(() =>
{
while (_currentSubscriptions.Count != 0)
{
_consumer.Poll(TimeSpan.FromSeconds(1));
}
_polling = false;
}, TaskCreationOptions.LongRunning).Start();
}
}

UI should not be freeze during background processing

I am working on legacy application (winform App) where I need to improve performance.
In this application, we are using MVP pattern and Shell usage reflection to find which presenter it needs to call in order to satisfied the user request. So there is a function which do the following tasks...
Find the appropriate presenter
Itrate through it's all methods to find out default method reference.
prepare an array for method's parameter inputs
Call the default method on presenter
return the presenter reference
here is some code...
public object FindPresenter(Type pType, string action, Dictionary<string, object> paramDictonary, string callerName = null)
{
if (pType == null)
{
throw new ArgumentNullException("presenterType");
}
var presenterTypeName = pType.Name;
var presenter = _presenterFactory.Create(pType);
presenter.CallerName = callerName;
if (presenter == null)
{
throw new SomeException(string.Format("Unable to resolve presenter"));
}
// Check each interface for the named method
MethodInfo method = null;
foreach (var i in presenter.GetType().GetInterfaces())
{
method = i.GetMethod(action, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance);
if (method != null) break;
}
if (method == null)
{
throw new SomeException(string.Format("No action method found"));
}
// Match up parameters
var par = method.GetParameters();
object[] results = null;
if (paramDictonary != null)
{
if (par.Length != paramDictonary.Count)
throw new ArgumentException(
"Parameter mis-match");
results = (from d in paramDictonary
join p in par on d.Key equals p.Name
orderby p.Position
select d.Value).ToArray();
}
// Attach release action
presenter.ReleaseAction = () => _presenterFactory.Release(presenter);
// Invoke target method
method.Invoke(presenter, results);
return presenter;
}
This method take around 15-20 second to complete and freeze the UI. I want to refector this method with some async processing so UI is not freeze during this method. As I need to return presenter reference, I thought of using wait() or join() method, but they will again lock the UI.
Please note, I am using .NET 4.0.
Unless you have millions of presenter types to search through, which is highly doubtful, and unless your average presenter has millions of parameters, which is also highly doubtful, there is nothing in the code that I see above that should take 15 seconds to execute.
So, the entirety of the delay is not in the code that you are showing us, but in one of the functions it invokes.
That could be in the very suspicious looking _presenterFactory.Create(pType); or in the implementation of paramDictionary if by any chance it happens to be a roll-your-own dictionary instead of a standard hash dictionary, or in the invocation of method.Invoke(presenter, results); itself.
Most likely in the last.
So, first of all, profile your code to find what the real culprit is.
Then, restructure your code so that the lengthy process happens on a separate worker thread. This may require that you pull considerable parts of your application out of the GUI thread and into that worker thread. Nobody said GUI programming was easy.
If the culprit is method.Invoke(), then this looks like something that you may be able to move to another thread relatively easily: Start that thread right before returning, and make sure everything that happens with each one of those presenter objects is thread safe.
But of course, these presenters are trying to actually render stuff in the GUI, then you will have to go and refactor all of them too, to separate their computationally expensive logic from the rendering logic, because WinForms can only be invoked from within its own thread.
The easiest approach is to use Application.DoEvents(); in your foreach loop to keep UI unlocked during long running processes
You may refer to MSDN system.windows.forms.application.doevents
But before using it you must also read Keeping your UI Responsive and the Dangers of Application.DoEvents
Well, based on your comment: "My question is how can I refector this by putting some tasks in background which do not lock the UI."
Try this:
class Program
{
static void Main(string[] args)
{
Task t1 = Task.Run(() => FindPresenter(typeof(Program), "boo"))
.ContinueWith(x => UsePresenter(x.Result));
while (true)
{
Thread.Sleep(200);
Console.WriteLine("I am the ui thread. Press a key to exit.");
if ( Console.KeyAvailable)
break;
}
}
static object FindPresenter(Type type, string action)
{
// Your FindPresenter logic here
Thread.Sleep(1000);
return (object)"I'm a presenter";
}
static void UsePresenter(object presenter)
{
Console.WriteLine(presenter.ToString());
Console.WriteLine("Done using presenter.");
}
}
Sorry I am not a Winforms guy.... In WPF we have Dispatcher for thread affinity issues. You might try this:
System.Windows.Threading.Dispatcher and WinForms?

Reactive Extensions: How to observe a IEnumerable method result async

i've a methode that return a IEnumerable of my business object. In this method i parse the content of a large text file to the business object model. There is no threading stuff in it.
In my ViewModel (WPF) i need to store and display the results of the method.
Store is an ObservableCollection.
Here ist the observable code:
private void OpenFile(string file)
{
_parser = new IhvParser();
App.Messenger.NotifyColleagues(Actions.ReportContentInfo, new Model.StatusInfoDisplayDTO { Information = "Lade Daten...", Interval = 0 });
_ihvDataList.Clear();
var obs = _parser.ParseDataObservable(file)
.ToObservable(NewThreadScheduler.Default)
.ObserveOnDispatcher()
.Subscribe<Ihv>(AddIhvToList, ReportError, ReportComplete);
}
private void ReportComplete()
{
App.Messenger.NotifyColleagues(Actions.ReportContentInfo, new Model.StatusInfoDisplayDTO { Information = "Daten fertig geladen.", Interval = 3000 });
RaisePropertyChanged(() => IhvDataList);
}
private void ReportError(Exception ex)
{
MessageBox.Show("...");
}
private void AddIhvToList(Ihv ihv)
{
_ihvDataList.Add(ihv);
}
And this is the parser code:
public IEnumerable<Model.Ihv> ParseDataObservable(string file)
{
using (StreamReader reader = new StreamReader(file))
{
var head = reader.ReadLine(); //erste Zeile ist Kopfinformation
if (!head.Contains("BayBAS") || !head.Contains("2.3.0"))
{
_logger.ErrorFormat("Die Datei {0} liegt nicht im BayBAS-Format 2.3.0 vor.");
}
else
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line.Length != 1415)
{
_logger.ErrorFormat("Die Datei {0} liegt nicht im BayBAS-Format 2.3.0 vor.");
break;
}
var tempIhvItem = Model.Ihv.Parse(line);
yield return tempIhvItem;
}
reader.Close();
}
}
}
Why do i don't get the results async? Before i see the results in my DataGrid, all items are parsed and delivered.
Can anybody help?
Andreas
Are you sure this isn't happening asynchronously? Are you assuming this based on what you perceive in the UI, or have you set breakpoints and determined that this is, in fact, the case?
Note that WPF's Dispatcher uses a priority queue, and DispatcherScheduler schedules items with Normal priority, which trumps the priority levels used for input, layout, and rendering. If the results come in quickly enough, then the UI may not get updated until after the last result has been processed: the dispatcher might be too busy processing results to perform layout and rendering of the UI.
You could try overriding the behavior of the DispatcherScheduler to schedule at a custom priority like so:
public class PriorityDispatcherScheduler : DispatcherScheduler
{
private readonly DispatcherPriority _priority;
public PriorityDispatcherScheduler(DispatcherPriority priority)
: this(priority, Dispatcher.CurrentDispatcher) {}
public PriorityDispatcherScheduler(DispatcherPriority priority, Dispatcher dispatcher)
: base(dispatcher)
{
_priority = priority;
}
public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)
{
if (action == null)
throw new ArgumentNullException("action");
var d = new SingleAssignmentDisposable();
this.Dispatcher.BeginInvoke(
_priority,
(Action)(() =>
{
if (d.IsDisposed)
return;
d.Disposable = action(this, state);
}));
return d;
}
}
And then modify your observable sequence by replacing ObserveOnDispatcher() with ObserveOn(new PriorityDispatcherScheduler(p)), where p is an appropriate priority level (e.g., Background).
Also, this looks highly suspect: ToObservable(NewThreadScheduler.Default). I believe this will cause a new thread to be created every time a result comes in, for the sole purpose of passing it to the dispatcher, after which the new thread will terminate. This is almost certainly not what you intended. I assume you simply wanted the file processed on a separate thread; as written, your code would literally end up creating 1,000 short-lived threads if your IEnumerable yields 1,000 items, none of which would actually be doing the work of reading the file.
Lastly, is OpenFile() being invoked on the dispatcher thread? If so, I believe what is going to happen is as follows:
Dispatcher (on UI thread) will call Subscribe(), which will process the chain of observable operators all the way back to ParseDataObservable(file).
Dispatcher will iterate through your IEnumerable sequence, firing each result into the observable sequence created by ToObservable().
Each result passed into the observable sequence will be scheduled for delivery on the dispatcher (the very same dispatcher that is currently running).
If this is the case, then the entire file will be read before any of the results get passed to AddIhvToList(), because the dispatcher is tied up reading the file and won't get around to processing the results in its queue until it has finished. If this is what is happening, you can try altering your code as follows:
var obs = _parser.ParseDataObservable(file)
.ToObservable()
.SubscribeOn(/*NewThread*/Scheduler.Default)
.ObserveOnDispatcher() // consider using PriorityDispatcherScheduler
.Subscribe<Ihv>(AddIhvToList, ReportError, ReportComplete);
Injecting SubscribeOn() should ensure that the iteration of your IEnumerable (i.e., the reading of the file) occurs on a separate thread. Scheduler.Default should suffice here, but you could use a NewThreadScheduler if you really need to (you probably don't). The dispatcher thread will return from Subscribe() after everything has been set up, freeing it up to continue processing its queue, i.e., passing the results to AddIhvToList() as they come in. This should give you the asynchronous behavior you desire.

Parallel.Invoke - Dynamically creating more 'threads'

I am educating myself on Parallel.Invoke, and parallel processing in general, for use in current project. I need a push in the right direction to understand how you can dynamically\intelligently allocate more parallel 'threads' as required.
As an example. Say you are parsing large log files. This involves reading from file, some sort of parsing of the returned lines and finally writing to a database.
So to me this is a typical problem that can benefit from parallel processing.
As a simple first pass the following code implements this.
Parallel.Invoke(
()=> readFileLinesToBuffer(),
()=> parseFileLinesFromBuffer(),
()=> updateResultsToDatabase()
);
Behind the scenes
readFileLinesToBuffer() reads each line and stores to a buffer.
parseFileLinesFromBuffer comes along and consumes lines from buffer and then let's say it put them on another buffer so that updateResultsToDatabase() can come along and consume this buffer.
So the code shown assumes that each of the three steps uses the same amount of time\resources but lets say the parseFileLinesFromBuffer() is a long running process so instead of running just one of these methods you want to run two in parallel.
How can you have the code intelligently decide to do this based on any bottlenecks it might perceive?
Conceptually I can see how some approach of monitoring the buffer sizes might work, spawning a new 'thread' to consume the buffer at an increased rate for example...but I figure this type of issue has been considered in putting together the TPL library.
Some sample code would be great but I really just need a clue as to what concepts I should investigate next. It looks like maybe the System.Threading.Tasks.TaskScheduler holds the key?
Have you tried the Reactive Extensions?
http://msdn.microsoft.com/en-us/data/gg577609.aspx
The Rx is a new tecnology from Microsoft, the focus as stated in the official site:
The Reactive Extensions (Rx)... ...is a library to compose
asynchronous and event-based programs using observable collections and
LINQ-style query operators.
You can download it as a Nuget package
https://nuget.org/packages/Rx-Main/1.0.11226
Since I am currently learning Rx I wanted to take this example and just write code for it, the code I ended up it is not actually executed in parallel, but it is completely asynchronous, and guarantees the source lines are executed in order.
Perhaps this is not the best implementation, but like I said I am learning Rx, (thread-safe should be a good improvement)
This is a DTO that I am using to return data from the background threads
class MyItem
{
public string Line { get; set; }
public int CurrentThread { get; set; }
}
These are the basic methods doing the real work, I am simulating the time with a simple Thread.Sleep and I am returning the thread used to execute each method Thread.CurrentThread.ManagedThreadId. Note the timer of the ProcessLine it is 4 sec, it's the most time-consuming operation
private IEnumerable<MyItem> ReadLinesFromFile(string fileName)
{
var source = from e in Enumerable.Range(1, 10)
let v = e.ToString()
select v;
foreach (var item in source)
{
Thread.Sleep(1000);
yield return new MyItem { CurrentThread = Thread.CurrentThread.ManagedThreadId, Line = item };
}
}
private MyItem UpdateResultToDatabase(string processedLine)
{
Thread.Sleep(700);
return new MyItem { Line = "s" + processedLine, CurrentThread = Thread.CurrentThread.ManagedThreadId };
}
private MyItem ProcessLine(string line)
{
Thread.Sleep(4000);
return new MyItem { Line = "p" + line, CurrentThread = Thread.CurrentThread.ManagedThreadId };
}
The following method I am using it just to update the UI
private void DisplayResults(MyItem myItem, Color color, string message)
{
this.listView1.Items.Add(
new ListViewItem(
new[]
{
message,
myItem.Line ,
myItem.CurrentThread.ToString(),
Thread.CurrentThread.ManagedThreadId.ToString()
}
)
{
ForeColor = color
}
);
}
And finally this is the method that calls the Rx API
private void PlayWithRx()
{
// we init the observavble with the lines read from the file
var source = this.ReadLinesFromFile("some file").ToObservable(Scheduler.TaskPool);
source.ObserveOn(this).Subscribe(x =>
{
// for each line read, we update the UI
this.DisplayResults(x, Color.Red, "Read");
// for each line read, we subscribe the line to the ProcessLine method
var process = Observable.Start(() => this.ProcessLine(x.Line), Scheduler.TaskPool)
.ObserveOn(this).Subscribe(c =>
{
// for each line processed, we update the UI
this.DisplayResults(c, Color.Blue, "Processed");
// for each line processed we subscribe to the final process the UpdateResultToDatabase method
// finally, we update the UI when the line processed has been saved to the database
var persist = Observable.Start(() => this.UpdateResultToDatabase(c.Line), Scheduler.TaskPool)
.ObserveOn(this).Subscribe(z => this.DisplayResults(z, Color.Black, "Saved"));
});
});
}
This process runs totally in the background, this is the output generated:
in an async/await world, you'd have something like:
public async Task ProcessFileAsync(string filename)
{
var lines = await ReadLinesFromFileAsync(filename);
var parsed = await ParseLinesAsync(lines);
await UpdateDatabaseAsync(parsed);
}
then a caller could just do var tasks = filenames.Select(ProcessFileAsync).ToArray(); and whatever (WaitAll, WhenAll, etc, depending on context)
Use a couple of BlockingCollection. Here is an example
The idea is that you create a producer that puts data into the collection
while (true) {
var data = ReadData();
blockingCollection1.Add(data);
}
Then you create any number of consumers that reads from the collection
while (true) {
var data = blockingCollection1.Take();
var processedData = ProcessData(data);
blockingCollection2.Add(processedData);
}
and so on
You can also let TPL handle the number of consumers by using Parallel.Foreach
Parallel.ForEach(blockingCollection1.GetConsumingPartitioner(),
data => {
var processedData = ProcessData(data);
blockingCollection2.Add(processedData);
});
(note that you need to use GetConsumingPartitioner not GetConsumingEnumerable (see here)

What is the difference between SynchronizationContext.Send and SynchronizationContext.Post?

Thanks to Jeremy Miller's good work in Functional Programming For Everyday .NET Development, I have a working command executor that does everything I want it to (do heavy lifting on the thread pool, send results or errors back to the synchronization context, and even post progress back to the synchronization context), but I can't explain why it uses SynchronizationContext.Send from the thread-pool and Synchronization.Post from the Func passed into the method that does the heavy lifting. I have read the documentation, several times, but I just can't get a gut sense for what the difference is. What am I supposed to get from the fact that one is called Send and one is called Post? I sense the magic is in the fact Send "starts a synchronous request" and Post "starts an asynchronous request", but both requests come from the thread pool and need to be sent/posted back to the UI thread.
Can someone explain the difference, even if it is just a mnemonic device that lets me know when to choose one over the other?
In case it matters, this is my test code where I use Post to send progress back to the UI:
private Action _ExecuteCommand
(SynchronizationContext context
, Action<int, int> progress
, Action<int, int> after)
{
int count = 3;
int accumulatedValue = 0;
int threadId = Thread.CurrentThread.ManagedThreadId;
for (int i = 0; i < count; i++)
{
Thread.Sleep(1000);
context.Post(delegate { progress(i + 1, threadId); });
accumulatedValue += i;
}
return () => after(threadId, accumulatedValue);
}
That _ExecuteCommand method is passed in as the command parameter below, mostly from the original article, that uses Send to send completion and error message back to the UI:
public void Execute(Func<Action> command, Action<Exception> error)
{
ThreadPool.QueueUserWorkItem(o =>
{
try
{
Action continuation = command();
_Context.Send(s => continuation());
}
catch (Exception e)
{
_Context.Send(s => error(e));
}
});
}
Send - synchronous: wait for answer (or action completed)
Post - asynchronous: drop off and continue
So your example uses the correct methods at the right moments. There is no need to halt the for-loop until the progress update is complete (on the contrary).
And Execute does want to wait for the Action to complete, otherwise the exception handling has no purpose.

Categories