Cs-Script & System.Diagnostics.Debug : Overriding Debug output traces - c#

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.
}

Related

Debug.Assert() has unexpected side effects - searching for alternatives

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);
}
}
}
}

can you make a method of an object accessible to all code in all threads?

Thank for all the interest in this question. Some of you have asked for more clarity on code involved, so in order to provide a bit more info, im going to edit it to provide a bit more detail.
Relating to my previous question, I am attempting to emulate a basic console in a WPF window (text output only). It's meant to work with a program that has a lot of code running in the background running on separate threads. This code relies heavily on a while loop as well, so my plan is to keep the WPF console window on the main thread (along with any additional GUI windows that might be needed) and execute all the code on separate threads.
The window has a WriteLine method used like so:
mainConsole.WriteLine("This is a message for the user.", SomeSender);
The rest of the code is going to need to call this method regularly.
Additional info:
The window itself is comprised of a Textblock wrapped in a Scroller. The WriteLine method of the window adds the message and formatting (font, font size, and colour - dependent on who the sender of the message is) to a List of objects which contain this information, and then displays the list of these messages including their formatting) as the content of the Textblock. The method works exactly as intended so doesn't need re-writing, it just needs to be accessible.
I've tried to keep this description as concise as possible. For more information, please see my previous question.
So my question now is: Is there an efficient way to make the window's WriteLine method usable to all threads from any class, thus enabling me to use it just like Console.WriteLine()?
While you have a number of options, it sounds like, in your case, it really does make sense for anyone, anywhere, to be able to write to your console. Given that, I'd create something like this:
public class MyConsole
{
public static event Action<string> TextWritten;
public static void Write(object obj)
{
string text = (obj ?? "").ToString();
if (TextWritten != null)
TextWritten(text);
}
public static void WriteLine(object obj)
{
Write(obj + "\n");
}
}
Then have your console form subscribe to the TextWritten event and, when text is written, write that text to the console. (Make sure to marshal to the UI thread first.)
The main advantage of using and event here, as opposed to having this class directly deal with your form, is that you can trivially add additional event handlers allowing you to interact with standard input/output, to add additional logging to files, to have multiple console forms open at once, etc. This flexibility can be useful for both debugging (i.e. additional writeouts to a flat file) and in production (allowing much easier redirection through standard in/out).
It seems you are trying to write a logging service that would allow you to access the log from anywhere within your code. You mention threads, so you will have to be mindful and handle that synchronization accordingly.
I would first create an ILogger interface such as this:
public interface ILogger
{
void Log(string line);
void Log(string format, params object[] args);
}
Then a proper Logger base class:
public abstract class Logger : ILogger
{
public abstract void Log(string line);
public virtual void Log(string format, params object[] args)
{
Log(string.Format(format, args));
}
}
Of course, you will need an actual implementation:
using System.Collections.Concurrent;
using System.Threading.Tasks;
public class ConcurrentLogger : Logger, ILogger, IDisposable
{
bool isDisposed;
BlockingCollection<string> loggedLines;
Action<string> callback;
public ConcurrentLogger(Action<string> callback)
{
if (callback == null)
throw new ArgumentNullException("callback");
var queue = new ConcurrentQueue<string>();
this.loggedLines = new BlockingCollection<string>(queue);
this.callback = callback;
StartMonitoring();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool isDisposing)
{
if (isDisposed) return;
if (isDisposing)
{
if (loggedLines != null)
loggedLines.CompleteAdding();
}
isDisposed = true;
}
public override void Log(string line)
{
if (!loggedLines.IsAddingCompleted)
loggedLines.Add(line);
}
protected virtual void StartMonitoring()
{
Task.Factory.StartNew(() =>
{
foreach (var line in loggedLines.GetConsumingEnumerable())
{
if (callback != null)
callback(line);
}
loggedLines.Dispose();
}, TaskCreationOptions.LongRunning);
}
}
For global access, you will need a Singleton class, so I would make this LogManagerclass:
public sealed class LogManager : ILogger
{
#region Singleton
static readonly LogManager instance = new LogManager();
public static LogManager Current { get { return instance; } }
private LogManager() { } // Disallow creating instances.
#endregion
ILogger logger;
public ILogger Logger { get { return logger; } }
public void StartLogging(ILogger logger)
{
if (logger == null)
throw new ArgumentNullException("logger");
this.logger = logger;
}
public void StopLogging(bool dispose = true)
{
var previousLogger = this.logger as IDisposable;
this.logger =null;
if (previousLogger != null && dispose)
previousLogger.Dispose();
}
public void Log(string line)
{
if (logger != null) logger.Log(line);
}
public void Log(string format, params object[] args)
{
if (logger != null) logger.Log(format, args);
}
}
With some quick initialization:
void InitializeLog()
{
var log = new ConcurrentLogger(LogToTextBox);
LogManager.Current.StartLogging(log);
}
void LogToTextBox(string line)
{
if (!CheckAccess())
{
this.Dispatcher.BeginInvoke((Action<string>)LogToTextBox,
DispatcherPriority.Background,
line);
return;
}
logTextBox.AppendText(line + Environment.NewLine);
}
Then anywhere in your code you can call: LogManager.Current.Log(...);
Create a static class that holds the WriteLine method and a Property referencing the window, control or whatever you need inside the writeline method.
Then add some code to your MainWindow constructor or loaded event to set the Reference-Property to the needed item.
Afterwards you can use Writeline from wherever you want.
BTW: This may be much cleaner using a static MainViewModel with an Instance getter, bind the DataContext of the MainWindow to this ViewModel and use the MVVM pattern. Youy would then only set some ConsoleOutput property or call an AddLine method or even Command from wherever you want and don't have to know how it is displayed by the View. You can test your app using unit tests, you can change the visual representation, ... all withou touching the logic of your application.
namespace {yourrootnamespace}
{
namespace GlobalMethods
{
static class ConsoleMethods
{
mainConsole mc;
public static WriteLine(string msg, object sender)
{
lock (this)
{
mc.WriteLine(msg, sender)
}
}
static ConsoleMethods()
{
mc = new mainConsole();
}
//more methods
}
}
And then: using {yourrootnamespace}.GlobalMethods;
Or alternatively let the methods take in a mainConsole argument which it then uses to call.

How can I monitor console.out?

I want to exit the program if I see some key words apprearing in Console.Out. This is because we use a third party DLL which has a problem that when it encounters some particular exception it never exits.
The only sulotion to us seems to be monitoring the log that is populated back to console.Out. And base on the log on console.out, the host application can edecide what to do when such exception are encountered.
Someone told me that I can use trace listener... but I am not sure about that.
what do you guys think?
The Console class provides the SetOut method which can be used to write output to a custom stream. For example, you could stream to a StringBuilder and monitor changes, or write a custom stream implementation that watches for the keywords.
For example, here is a KeywordWatcherStreamWrapper class that watches for specified keyword, and raises an event for all listeners whenever the keyword is seen:
public class KeywordWatcherStreamWrapper : TextWriter
{
private TextWriter underlyingStream;
private string keyword;
public event EventHandler KeywordFound;
public KeywordWatcherStreamWrapper(TextWriter underlyingStream, string keyword)
{
this.underlyingStream = underlyingStream;
this.keyword = keyword;
}
public override Encoding Encoding
{
get { return this.underlyingStream.Encoding; }
}
public override void Write(string s)
{
this.underlyingStream.Write(s);
if (s.Contains(keyword))
if (KeywordFound != null)
KeywordFound(this, EventArgs.Empty);
}
public override void WriteLine(string s)
{
this.underlyingStream.WriteLine(s);
if (s.Contains(keyword))
if (KeywordFound != null)
KeywordFound(this, EventArgs.Empty);
}
}
Sample usage:
var kw = new KeywordWatcherStreamWrapper(Console.Out, "Hello");
kw.KeywordFound += (s, e) => { throw new Exception("Keyword found!"); };
try {
Console.SetOut(kw);
Console.WriteLine("Testing");
Console.WriteLine("Hel");
Console.WriteLine("lo");
Console.WriteLine("Hello");
Console.WriteLine("Final");
} catch (Exception ex) { Console.Write(ex.Message); }
On the second Write statement which contains the entire keyword, the event will be raised and thus the exception will be thrown. Note also that this silently wraps the underlying stream and still writes to it, so console output is still generated as normal.
Sample output:
Testing
Hel
lo
Hello
Keyword found!
if you can wrap this into an exe, maybe you can use Process.StandardOutput.

Returning updates from a method

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.

Is this an Observer Anti-Pattern? (with bonus state machine question)

I am wondering if the following is bad use of the Observer pattern. I know the Subject is supposed to be the one and the listener the many. However, I could end up with more subjects in my application than listeners!
The Players
Form1: Self explanatory
DocumentCreator: Contains a Factory Method and a Strategy for picking a file from a list
Document: Contains information about the document file and a Template method for children
Proposed
IErrorProne: interface for the above players to implement an event, turning them into subjects
Reporting: listens for IErrorProne objects and handles logging/emailing
DocumentState: This is a bonus that Im a bit iffy on. I havent quite settled on a good flow outside of the template. Currently I have a state machine inside the Document class. I want to pull the state machine out of the Document class and into Form1, decoupling the two from each other.
public interface IErrorProne
{
public delegate void ErrorEventDelegate(
object sender,
ErrorEventArgs e
);
public event ErrorEventDelegate ReportError;
}
public abstract class Document : IDisposable, IErrorProne // My Template
{
public void Process()
{
//Error Occured
OnReportError(); // safely triggers error reporting
}
}
public class Reporting
{
static Reporting instance = new Reporting();
public void HandleError(object sender, ErrorEventArgs e);
}
public partial class Form1
{
private DocumentCreator docFactory
= new DocumentCreator(new RandomPicking());
private Document theDoc = null;
private Reporting reporting = Reporting.Instance;
private DocState state = new InitialState();
//DocState not in this example but demonstrates how it might work
public Form1()
{
docFactory.ReportError += reporting.HandleError;
theDoc.ReportError += reporting.HandleError;
docFactory.ReportError += state.HandleError;
theDoc.ReportError += state.HandleError;
}
void BackgroundWork(...)
{
using (theDoc = DocumentFactory.Instance.CreateDocument())
{
if (theDoc != null)
theDoc.Process();
}
}
}
I guess my question is it an Anti-Pattern if I have a Many to One, rather than a One to Many?
If you think of it as publish-subscribe, then it really doesn't matter. If you take the Domain Event style, you can have anything and any number of things publish any given domain event, and anything and any number of things subscribe to domain events.
Many->Many, many->one, one->many are all valid.

Categories