I'm frequently using asserts to detect unexpected program states. I thought an assert is a conditional message box the immediately stops all threads so that (on pressing "Retry") I can inspect the current application state.
This is not the case! While the assert message is open, my wpf application continues processing events. It is absurd, as on breaking into the debugger the situation might be totally different compared to what the assert "saw" initially. You can have the case that the check for the assert to fire changes through the assert itself, you can have recursive execution of methods - with the consequence of multiple asserts or states in which the program would never come normally.
As far as I understand the assert-function, this is a problem by design. The dialog runs on the same GUI thread as the application itself and hence needs to process messages for its own purpose. But this often has the described side-effects.
So I'm searching for an assert alternative that fulfills the requirement to stop all running threads when invoked. As workaround, I sometimes use "Debugger.Break();" which has (unfortunately) no effect if started without debugger.
For illustrating the problem, please see the following code snipped that in the most simplified manner produces some phenomenons:
public partial class MainWindow : Window
{
int _count = 0;
public MainWindow()
{
InitializeComponent();
}
private void onLoaded(object sender, RoutedEventArgs e)
{
test();
}
protected override void OnLocationChanged(EventArgs e)
{
base.OnLocationChanged(e);
}
void test()
{
++_count;
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() =>
{
test();
}));
Trace.TraceInformation(_count.ToString());
Debug.Assert(_count != 5);
}
}
On running the code, watch the output panel of the developer studio. You will see the numbers go up to 5, then the assert fires. But while the dialog is open, the numbers are still increasing. Hence the condition of the assert changes while the assert is open!
Now check the main window –it’s still responsive. Set a breakpoint at “base.OnLocationChanged(e);“ and move the main window => you will hit the break point. But mind the callstack:
MainWindow.OnLocationChanged(System.EventArgs e)
(…)
System.dll!Microsoft.Win32.SafeNativeMethods.MessageBox(System.IntPtr
System.dll!System.Diagnostics.AssertWrapper.ShowMessageBoxAssert(stri
System.dll!System.Diagnostics.DefaultTraceListener.Fail(string message, str
System.dll!System.Diagnostics.DefaultTraceListener.Fail(string message)
System.dll!System.Diagnostics.TraceInternal.Fail(string message)
System.dll!System.Diagnostics.Debug.Assert(bool condition)
MainWindow.test()
MainWindow.test.AnonymousMethod__0()
This clearly shows that arbitrary code can be executed while the assert is open.
So I'm searching for an assert like mechanism that stopps all existing threads and runns in it's own (thread-) context.
Any ideas?
You are finding out more about how the dispatcher loop works. And yes, the MessageBox that the default trace listener uses to report the failure does not do much to stop your program. It was designed to stop the user, it is a modal dialog box that disables all user input. But does not stop anything that you do in your code. Like it calling Dispatcher.BeginInvoke().
You will need another implementation of the TraceListener.Fail() method. That's quite possible, edit your App.xaml.cs file and make it look similar to this:
using System.Diagnostics;
...
public partial class App : Application {
public App() {
if (Debugger.IsAttached) {
var def = Debug.Listeners["Default"];
Debug.Listeners.Remove(def);
Debug.Listeners.Add(new MyListener(def));
}
}
private class MyListener : TraceListener {
private TraceListener defListener;
public MyListener(TraceListener def) { defListener = def; }
public override void Write(string message) { defListener.Write(message); }
public override void WriteLine(string message) { defListener.WriteLine(message); }
public override void Fail(string message, string detailMessage) {
base.Fail(message, detailMessage);
Debugger.Break();
}
}
}
The code works by removing the DefaultTraceListener, the one that's giving you a headache, from the installed listeners. And adds a custom one, the MyListener class. Which doesn't do much, just uses the original listener to get messages displayed in the Output window. But with an override for the Fail() message, it automatically triggers a debugger break. Just what you want here.
I'm answering my own question as summary and extension of the provided information by Jon Skeet and Hans Passant:
For the case the program runs in the debugger the option with Debugger.Break() or enabling the EEMessageException is for me the way to go. Both methods immediately stop all threads.
If not debugging and the assert occurs in the GUI thread a message box running on a separate thread helps (see http://eprystupa.wordpress.com/2008/07/28/running-wpf-application-with-multiple-ui-threads/)
Here is the code putting all together (by extending the suggestion from Hans Passant)
public partial class App : Application
{
public App()
{
var def = Debug.Listeners["Default"];
Debug.Listeners.Remove(def);
Debug.Listeners.Add(new MyListener(def, Dispatcher.CurrentDispatcher));
}
private class MyListener : TraceListener
{
private TraceListener _defListener;
private Dispatcher _guiDisp;
public MyListener(TraceListener def, Dispatcher guiDisp)
{
_defListener = def;
_guiDisp = guiDisp;
}
public override void Write(string message) { _defListener.Write(message); }
public override void WriteLine(string message) { _defListener.WriteLine(message); }
public override void Fail(string message, string detailMessage)
{
base.Fail(message, detailMessage); //write message to the output panel
if (Debugger.IsAttached)
{
//if debugger is attached, just break => all threads stopped
Debugger.Break();
}
else if (Dispatcher.CurrentDispatcher == _guiDisp)
{
//running standalone and called in the GUI thread => block it
Thread anotherGuiThread = new Thread(() =>
{
//TODO: nice dlg with buttons
var assertDlg = new Window() { Width = 100, Height = 100 };
assertDlg.Show();
assertDlg.Closed += (s, e) => assertDlg.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run(); //run on its own thread
});
anotherGuiThread.SetApartmentState(ApartmentState.STA);
anotherGuiThread.Start();
anotherGuiThread.Join();
}
else
{
//running standalone and NOT called in the GUI thread => call normal assert
_defListener.Fail(message, detailMessage);
}
}
}
}
Related
I have an interface like this
public interface IServerDataProvider
{
string Val1 { get; }
string Val2 { get; }
event EventHandler<EventArgs> Val1Changed;
event EventHandler<EventArgs> Val2Changed;
}
It gives the user access to two strings retrieved from a server and events that are triggered when these strings change.
Learning about async-await in c#, I can make a fairly simple implementation that periodically checks if these values are changed on a server :
public class ServerDataProviderAsync : IServerDataProvider
{
public event EventHandler<EventArgs> Val1Changed;
public event EventHandler<EventArgs> Val2Changed;
private string _val1Url = "someUrl";
private string _val2Url = "otherUrl";
private const int _delayMs = 1000;
public ServerDataProviderAsync()
{
Start();
}
private async void Start()
{
Val1 = await DownloadString(_val1Url);
Val2 = await DownloadString(_val2Url);
Val1UpdateLoop();
Val2UpdateLoop();
}
private async void Val1UpdateLoop()
{
await Task.Delay(_delayMs);
Val1 = await DownloadString(_val2Url);
Val1UpdateLoop();
}
private async void Val2UpdateLoop()
{
await Task.Delay(_delayMs);
Val2 = await DownloadString(_val1Url);
Val2UpdateLoop();
}
private string _val1;
public string Val1
{
get { return _val1; }
private set
{
if (_val1 != value && value != null)
{
_val1 = value;
OnContentChanged(Val1Changed);
}
}
}
private string _val2;
public string Val2
{
//similar to Val1
}
private async Task<string> DownloadString(string url)
{
using (var wb = new WebClient())
{
try { return await wb.DownloadStringTaskAsync(url); }
catch { /*log error*/}
}
return null;
}
private void OnContentChanged(EventHandler<EventArgs> handler)
{
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
And it can be used something like this from MainWindow :
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var dataProvider = new ServerDataProviderAsync();
//hook up to events and display strings in GUI
}
}
Now my question is if this is a good implementaion? Is there a better way?
The first part I'm worried about are the async void methods. I've read they should only be used for event handlers. Are they bad in this case? And if so, why?
The other thing I'm worried about is the recursive way the update loops work. But it seems that since it always awaits tasks that are not already finished, it will not keep adding to the call stack.
You should really use an [iterative] infinite loop to create an infinite loop rather than using infinite recursion.
Using recursion means constantly spending the effort to re-create the exact same state machine from scratch each iteration instead of using the perfectly fine state machine that you already have, and it needlessly obfuscates the code and reduces clarity (to the point that you yourself weren't even sure of the possible negative repercussions; you don't want every single other person who reads the code to have to think through the same problem) for no real gain. Additionally, if you want to be able to propagate exceptions generated in this method to the caller (discussed further below) then using recursion has a number of problems, such as completely messing up the call stack, making actually throwing the exception through all of those levels difficult, and also creating a memory leak in that each "finished" state machine wouldn't be able to be cleaned up.
As for the methods being void, that's not particularly problematic. The reason that one would normally want a Task returned is so that you can tell when the operation finishes. Your operations never finish, they run forever. Getting a task that will never be completed isn't really any more or less useful than not getting a task at all in most circumstances.
The only way it might be relevant is error handling. If your loop generates an error and the method is void it needs to be responsible for handling that error itself, because it is conceptually a top level method. If it returns a Task then it gets the luxury of simply throwing that exception to its caller and leaving that caller responsible for handling that Exception. This would be the only reason to not return void for a method that is supposed to run forever.
I am working on a VS project/solution that is used by different applications. My job is to refactor the project and change it from using xxxAsync method to using BeginInvoke.
I came up to something similar to the following code:
public class AsyncTestModel {
private delegate string DoTaskDelegate();
public static EventHandler<TaskCompletedEventArgs> OnTaskCompleted;
public static void InvokeTask() {
DoTaskDelegate taskDelegate = Task;
taskDelegate.BeginInvoke(new AsyncCallback(TaskCallback), null);
}
private static string Task() {
Thread.Sleep(5000);
return "Thread Task successfully completed.";
}
private static void TaskCallback(IAsyncResult ar) {
string result = ((DoTaskDelegate)((System.Runtime.Remoting.Messaging.AsyncResult)ar).AsyncDelegate).EndInvoke(ar);
if (OnTaskCompleted != null) {
OnTaskCompleted(null, new TaskCompletedEventArgs(result));
}
}
}
public class TaskCompletedEventArgs : EventArgs {
private string _message;
public TaskCompletedEventArgs(string message) : base() {
_message = message;
}
public string Message {
get {
return _message;
}
}
}
I've tested this on a new UI project I've created. The UI project contains a button and a label controls. The UI has the following code:
private void button1_Click(object sender, EventArgs e) {
AsyncTestModel.OnTaskCompleted += OnTaskCompleted;
AsyncTestModel.InvokeTask();
}
private void OnTaskCompleted(object sender, TaskCompletedEventArgs e) {
UpdateLabel(e.Message);
}
private void UpdateLabel(string message) {
this.label1.Text = message;
}
After running this, I've encountered the cross-thread exception saying the the control 'label1' is being accessed from other thread aside the thread that it was created.
Is there a way for me to invoke the OnTaskCompleted event handler on the same thread that calls the BeginInvoke method? I know I could just use the form's InvokeRequired and call the form's BeginInvoke like the following:
private delegate void DoUpdateLabelDelegate(string message);
private void UpdateLabel(string message) {
if (this.InvokeRequired) {
IAsyncResult ar = this.BeginInvoke(new DoUpdateLabelDelegate(UpdateLabel), message);
this.EndInvoke(ar);
return;
}
this.label1.Text = message;
}
But the solution above will require me to ask and apply that solution to the other development team handling applications that uses my project/solution. Those other developers shouldn't be required to know that the methods hooked to the event handler are running from different thread.
Thanks, in advance.
As designed, no, you have absolutely no idea which thread is the one on which the client's UI runs.
You can arbitrarily demand that your InvokeTask() is to be called from that UI thread. Now you know, you can copy SynchronizationContext.Current in the InvokeTask() method and, later, call its Post() or Send() method to call a method that fires the event. This is the pattern used by, for example, BackgroundWorker and async/await. Do note that copying the Current property is required to make this work, don't skip it.
That of course still won't work when your InvokeTask() method is not called from the UI thread, you'll see that Synchronization.Current is null and have no hope to marshal the call. If that's a concern then you could expose a property of type ISynchronizeInvoke, call it SynchronizingObject. Now it is up to the client code to make the call, they'll have no trouble setting the property, they'll simply assign this in their form class constructor. And you use the property's Post or Send method to call the method that raises the event. This is the pattern used by for example the Process and FileSystemWatcher classes. Don't use it if you expect your library to be used by non-Winforms client apps, unfortunately later GUI libraries like WPF and Silverlight don't implement the interface. Otherwise the exact same problem with approaches like calling Control.Begin/Invoke() yourself.
try to use this, maybe it can help you.
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
//Do something...
});
I started a small app (C#, .Net4, console app) and it was a basic idea for moving files around at home based on rules.
This app has grown and become extremely useful. So my task is to break it into more reusable classes and smaller projects (class libraries).
I have a generic 'Show' function that accepts a string, and a error_level id. Based on that, I would output text to my console window in a certain colour. All is fine when it's all in one big class, but I want to move a method to it's own class libabry - however, I want it to report updates while it's processing, to my UI (Console window, for now). When I move it to the class, obviously, class to my 'Show' method', break.
Is there a way I can get messages sent from my class method, back to my UI? It's messages like, 'Opened Config file', 'Processing 12 new files', 'Success'.
And as it happens, the UI gets the messages and displays them, while the method finishes it's job.
At the moment, it's a Console App project. My plan is to rip out the working code, keeping the console app for testing, and later, change the 'UI' into a nice WPF desktop application. (I'm trying to learn WPF, and decided to use a small project I started ages ago, and 'skin it').
I would suggest that you add an interface, implement that interface in your UI, and pass a reference to the class that implements the interface to your new classes.
This approach should work if you are performing the work in a single thread or multiple threads.
For example, the interface:
public interface INotify
{
void Notify(string Msg);
}
the UI:
public class Form1 : INotify
{
// This is the method where you instantiate the new worker process
public void DoSomeWork() {
NewClass Worker = New NewClass(this);
}
public delegate void NotifyDelegate(string Msg);
public void Notify(string Msg)
{
txtLog.Text += Msg + Environment.NewLine;
}
void INotify.Notify(string Msg)
{
this.INotify_Notify(Msg);
}
private void INotify_Notify(string Msg)
{
if (this.InvokeRequired)
{
this.Invoke(new NotifyDelegate(Notify), Msg);
}
else
{
this.Notify(Msg);
}
}
}
and the new class (just call notify in this class to send the message):
public class NewClass
{
private INotify m_Notifier;
private void Notify(string Msg)
{
m_Notifier.Notify(Msg);
}
public NewClass(INotify oNotifier)
{
m_Notifier = oNotifier;
}
}
Update with alternate implementation
An alternate implementation, which will work with static classes, is to implement a delegate.
For example, here is the delegate:
public delegate void NotifyDelegate(string Msg);
Here is the sample static class for the console app:
static class Program
{
private static NotifyDelegate m_Notifier;
static void Main(string[] args)
{
m_Notifier = new NotifyDelegate(Notify);
NewClass oNewClass = new NewClass(m_Notifier);
// Your work code here
}
static void Notify(string Msg)
{
Console.WriteLine(Msg);
}
}
and a revised version of the work class:
public class NewClass
{
private NotifyDelegate m_Notifier;
public void Notify(string Msg)
{
m_Notifier.Invoke(Msg);
}
public NewClass(NotifyDelegate oNotifier)
{
m_Notifier = oNotifier;
}
}
If i understand your question correctly i would implement event handling so that your UI can subscribe to some sort of status event.
An alternative would be to use some kind of Logging Framework like NLog and log to a static method in your UI via the methodCall target.
Since you are using WPF it would make sense to use MVVM. This would probably be the best way to create powerful and maintainable UIs.
Well this is usually done with Binding, you bind your viewModel with the view, and any changes to the viewModel, will be directly displayed in your UI.
Could the class/es that do work raise an event that the class on the UI thread is listening to? The 'worker' class would raise an event with some parameters, the listener class would then write that information to the UI.
Okay, I think the title can be quite confusing... :)
My application is using CS-Script as a script interface.
In the scripts my application will be running, I want to have some sort of "Debug print" - meaning somewhere in the script the scripter can do "Debug.Print("BLAAAAH!!!");") and that would show up somewhere in my very funky output dialog.
Of course I can create my own debug-ooutput-stuff, but since I'm using C# as a scripting language and people using C# would be used to use System.Diagnostics and use Debug.Print("..."),
it would be great if I could reroute System.Diagnostics.Debug.Print("") and System.Diagnostics.Debug.WriteLine("...") to trace their output to my cool output-window.
So.
Does anybody know if it's possible to reroute C#'s System.Diagnostic.Debug print/writeline output to something I have control over ?
For that, you can create a custom TraceListener.
You should set the compile time DEBUG symbol or run the script with /dbg option
cscs /dbg <yourScript>
You will also need to create a custom TraceListener or simply use a trace viewer like the sysinternals DebugView
I use the TraceListener for this also, but here's my code snippets:
Classes:
using System.Diagnostics;
public class DebugOutputListener : TraceListener
{
public event EventHandler<DebugMessageArgs> DebugMessage;
public override void Write(string message)
{
EventHandler<DebugMessageArgs> h = DebugMessage;
if (h != null)
{
DebugArgs args = new DebugArgs
{
Message = message
};
h(this, args);
}
}
public override void WriteLine(string message)
{
Write(message + "\r\n");
}
}
public class DebugMessageArgs : EventArgs
{
public string Message
{
get;
set;
}
}
To receive debug messages, instantiate an instance of the DebugOutputListener, subscribe to the DebugMessage event handler and register the listener with the Debug.Listeners collection.
e.g.
private void InitialiseDebugListener()
{
DebugListener dl = new DebugListener();
dl.DebugMessage += new EventHandler<DebugArgs>(Console_OnDebugMessage);
Debug.Listeners.Add(dl);
}
private void Console_OnDebugMessage(object sender, DebugMessageArgs e)
{
string debugMessage = e.Message;
// Do what you want with debugMessage.
// Be aware this may not come in on the application/form thread.
}
I have a class that basically stores files in amazon s3.
Here is what it looks like (simplified)
public class S3FileStore
{
public void PutFile(string ID, Stream content)
{
//do stuff
}
}
In my client app, I want to be able to call:
var s3 = new() S3FileStore();
s3.PutFile ("myId", File.OpenRead(#"C:\myFile1"));
s3.PutFile ("myId", File.OpenRead(#"C:\myFile2"));
s3.PutFile ("myId", File.OpenRead(#"C:\myFile3"));
I want this to be an asynchronous operation - I want the S3FileStore to handle this (i don't want my caller to have to execute PutFile asynchronously so to speak) but, i want to be able to trap exceptions / tell if the operation completed for each file.
I've looked at event based async calls, especially this:
http://blogs.windowsclient.net/rendle/archive/2008/11/04/functional-shortcuts-2-event-based-asynchronous-pattern.aspx
However, I can't see how to call my PutFile (void) method?
Are there any better examples?
Look at the solution for this question: Adding cancel ability and exception handling to async code . Hope it helps.
The BackgroundWorker base class might be worth a look, and also the Thread Pool:
ThreadPool.QueueUserWorkItem(delegate
{
s3.PutFile ("myId", File.OpenRead(#"C:\myFile1"));
});
This is basically what you would do with the Action/BeginInvoke pattern. With BeginInvoke, you additionally receive an IAsyncResult on which you can call .WaitOne() to block the current thread until the operation finished, in case you need that. You would trigger a new BeginInvoke for every file you'd like to save.
If you need to do this frequently, a more sophisticated version could be to use a Queue in combination with the BackgroundWorker, e.g.:
public sealed class S3StoreLikePutFileWorker<TYourData> : BackgroundWorker
{
private AutoResetEvent WakeUpEvent = new AutoResetEvent(false);
private Queue<TYourData> DataQueue = new Queue<TYourData>();
private volatile bool StopWork = false;
public void PutFile(TYourData dataToWrite)
{
DataQueue.Enqueue(dataToWrite);
WakeUpEvent.Set();
}
public void Close()
{
StopWork = true;
WakeUpEvent.Set();
}
private override void OnDoWork(DoWorkEventArgs e)
{
do
{
// sleep until there is something to do
WakeUpEvent.WaitOne();
if(StopWork) break;
// Write data, if available
while(DataQueue.Count > 0)
{
TYourData yourDataToWrite = DataQueue.Dequeue();
// write data to file
}
}
while(!StopWork);
}
}
Depending on how much complexity you need.
The BackgroundWorker supports progress feedback (set WorkerReportsProgress = true; in the constructor), and you can also add a custom event to report errors, if that is necessary:
// create a custom EventArgs class that provides the information you need
public sealed class MyEventArgs : EventArgs {
// Add information about the file
}
// ... define the event in the worker class ...
public event EventHandler<MyEventArgs> ErrorOccured;
// ... call it in the worker class (if needed) ...
if(ErrorOccured != null) ErrorOccured(this, new MyEventArgs(/*...*/));