A simple .NET messaging system - c#

I am trying to create a system to send messages between components in C# (using the Mono runtime). Here is some pseudo-code of what I am trying to achieve in terms of functionality:
Creating the Message
MyMessage : BaseMessage {}
AnotherMessage : BaseMessage { string data; }
Subscribing
MyMessage.Subscribe(MyMessageHandler)
AnotherMessage.Subscribe(AnotherMessageHandler)
Message Handlers
void MyMessageHandler(MyMessage message)
{
// code
}
void AnotherMessageHandler(AnotherMessage message)
{
// code
}
Sending the Message
MyMessage.Send(MyMessageInstance);
AnotherMessage.Send(AnotherMessageInstance);
Additional Information
Each message handler will only take one type of message, and that message may or may not have a payload of any type (for example a string called data).
I have a working solution in C++ (see below for the subscribing part):
// A function-style macro is used to call this method
template <typename Type, typename Caller>
void subscribe(boost::function<void(const Type&)> subscriber, boost::shared_ptr<Caller> caller)
{
m_subscriptions[typeid(Type)].connect(Subscribers::slot_type([subscriber](const BaseMessage& message)
{
subscriber(static_cast<const Type&>(message));
}).track(caller));
}
For those not familiar with boost::signals2, .track creates a weak pointer to the caller and disconnects the subscriber when it is destroyed.
I am aiming for something similar in C#, but am struggling to do so. This is what I have so far:
abstract class Message<MessageArgType>
{
public delegate void Handler(MessageArgType arg);
private event Handler subscribers;
public void Subscribe(Handler subscriber)
{
subscribers += subscriber;
}
public void Unsubscribe(Handler subscriber)
{
subscribers -= subscriber;
}
public void Send(MessageArgType arg)
{
subscribers.Invoke(arg);
}
}
It seems to me that this will store a strong reference to the object that the message handler belongs to. After a lot of googling, I ended up finding this. However, as someone quite new to C#, I found this quite difficult to grasp what was going on. Also, this post was made in 2007, so there may be a better solution now, but I am struggling to find one.
To conclude
Could someone please provide me with some guidance on how to get a weak reference from a delegate in a thread-safe (due to the GC running on another thread) manner that can achieve an interface similar to the pseudo code above?

In a case of "No matter how much you know, there's always plenty more", I did some more research and discovered that .NET 3 added the WeakEventManager class.
http://msdn.microsoft.com/en-us/library/aa970850(v=vs.110).aspx
To use the Generic WeakEventManager class, do this:
WeakEventManager<EventSource, SomeEventEventArgs>
.AddHandler(source, "SomeEvent", source_SomeEvent);
EDIT:
In your case, you would probably do something like this:
public void Subscribe(Handler subscriber)
{
WeakEventManager<Message, MessageArgType>
.AddHandler(this, "subscribers", subscriber);
}

Related

Is there a way to handle the event when a new thread is created in the current process?

I want to able to detect when a new thread is created e.g. Task.Run and, if possible, handle when its closed.
I know it's possible to get the current threads being handled by your process via Process.GetCurrentProcess().Threads and that's somewhat useful. What I want though it's to handle when a new thread begin it's execution, from a perspective that I don't know where it's been created.
Some background
As it was asked, I'm putting here some detail to the actual problem I'm running into, because maybe I'm searching for the least optimal solution.
I'm developing a large system with multiple screen, each one with a bunch of controls, which some of them are custom. Recently, the team has gradually been adopting async/await patterns and the issue of locking the UI untill a task is completed has risen. We created a loading panel in our base form, exposing a hide and show method to be called by the implementations of this base form. The problem here is returning to all those forms that are already implemented and placing calls to those methods throughout the code, especially async events. Here I wonder if there's an easier solution that will work for the past implementations and eliminate the need of calling methods between events.
What we are doing as in today, is something along the lines:
public class BaseForm {
public ShowPanel(){
...
}
public HidePanel(){
...
}
}
public class FormImplementation : BaseForm {
private async void OnEventAsync(object sender, EventArgs e){
ShowPanel();
// await stuff
HidePanel();
}
}
I find it to be quite cumbersome to manually place those calls around event handlers. I'd do some metaprogramming karate, but I'm not experienced with it in C#.
maybe I'm searching for the least optimal solution.
Examining threads is definitely an incorrect approach. For one, async doesn't use threads, so that approach would not have worked.
I find it to be quite cumbersome to manually place those calls around event handlers. I'd do some metaprogramming karate, but I'm not experienced with it in C#.
Metaprogramming is one option, and a pretty decent one. PostSharp and Fody are both highly regarded. The "do something at the beginning and end of these methods" is a common problem in that field, and metaprogramming is a definite option. I think what you actually want is something like this:
public class BaseForm {
public ShowPanel() {
...
}
public HidePanel() {
...
}
}
public class FormImplementation : BaseForm {
private async void OnEventAsync(object sender, EventArgs e) {
ShowPanel();
try { ... }
finally { HidePanel(); }
}
}
You can minimize the code changes by using a disposable, e.g., (using my Nito.Disposables library) with a C# 8 using declaration:
public class BaseForm {
public IDisposable ShowPanel() {
...
return new AnonymousDisposable(HidePanel);
}
private void HidePanel() {
...
}
}
public class FormImplementation : BaseForm {
private async void OnEventAsync(object sender, EventArgs e) {
using var _ = ShowPanel();
...
}
}
There are other alternatives, such as changing the return type of OnEventAsync to be Task, but that would require more code changes I think than just doing the above.

Show dialog from non UI dll

I'm building a dll that will be used from wpf and other kind of framework (windows form, asp...). For this reason I don't want to use Messagebox. Which is the best way to send notification from dll to app and each decide the way to show the message to user (and wait an answer from user)? Somebody can help me to find the correct way?
Unless the library (.dll) is only intended to work with a particular UI, the library shouldn't "decide" how or if notifications get displayed. It's a separation of concerns. If a library determined that it should show a MessageBox then you wouldn't be able to use that same library with a web app or some out-of-sight service.
Here are two ways (not exhaustive) that we might get information from a separate library, including our own:
We call a function and the library returns a response. For example, it might indicate that an action succeeded or failed. The library doesn't know what type of app it's being called from or whether anyone needs to see the response. It just returns it. Your app can then receive that result and display a message.
A class within the library raises an event which indicates that something has happened. Same thing - it doesn't know what is listening for that even or what will happen as a result. It just raises the notification. Our app determines that in response to that event it should display a message.
When our libraries work that way they are easier to test using automated tests like unit tests and integration tests. It's easy to write a test which verifies that calling a method returns a certain result. It's much harder to verify that a MessageBox pops up.
And, as mentioned, it makes it more likely that we can use more of our code with different types of user interfaces. For those reasons it's beneficial to write as much of our code as possible in isolation from any UI, which means not including input/output behaviors that are specific to one type of UI.
You could expose an event that the consumers can subscribe to. Here is the general pattern to do this kind of thing:
You can create your own class to carry the data about the event:
public class NotificationEventArgs : EventArgs
{
public NotificationEventArgs(string message)
{
Message = message;
}
public string Message { get; }
}
You then create a delegate to represent the signature of the event:
public delegate void OnNotificationEventHandler(SomeClass sender, NotificationEventArgs args);
Your class or classes can then expose this delegate as an event:
public class SomeClass
{
private OnNotificationEventHandler _notificationEventHandler;
public event OnNotificationEventHandler OnNotification
{
add { _notificationEventHandler += value; }
remove { _notificationEventHandler -= value; }
}
protected void RaiseNotificationEvent(NotificationEventArgs args)
{
_notificationEventHandler?.Invoke(this, args);
}
public void SomeMethod()
{
//Your class does something that requires consumer notification
var args = new NotificationEventArgs("Something happened!");
//Raise the event for the consumers who are listening (if any)
RaiseNotificationEvent(args);
}
}
Finally, your consuming classes will subscribe to this event:
SomeClass obj = new SomeClass();
obj.OnNotification += Obj_OnNotification;
private static void Obj_OnNotification(SomeClass sender, NotificationEventArgs args)
{
//Handle the notification from the class here.
Console.WriteLine(args.Message);
}
The general idea is that consumers of your class only need to know that something has happened as well as details of what happened. How that event is consumed, handled or displayed is not the responsibility of your component.

C# xUnit Test listeners

I'm building a selenium test framework based on .Net Core and the team decided to go with xUnit. All's well and good everything has been going ok but for a while now, we've been trying to replicate the functionality of Java TestNG listeners without much luck.
I've been digging around the xunit git repo and found a few instances where some interfaces such ITestListener have been used. After digging deeper, I found that these listeners are from a package called TestDriven.Framework and I wanted to know exactly how would I use a test listener created using those interfaces?
So far this is my simple test listener that should write something when the test fails:
public class Listener
{
readonly int totalTests;
public Listener(ITestListener listener, int totalTests)
{
this.totalTests = totalTests;
TestListener = listener;
TestRunState = TestRunState.NoTests;
}
public ITestListener TestListener { get; private set; }
public TestRunState TestRunState { get; set; }
public void onTestFail(ITestFailed args)
{
Console.WriteLine(args.Messages);
}
}
Now, I know you can do this inside a tear down hook but remember, this is just a simple example and what I have in mind is something more complex. So to be precise, where/how exactly would I register the test to use this listener? In Java TestNg I would have #Listeners but in C# I'm not too sure.
Edit 1 so the example worked and managed to add it to my own project structure but when I try to use this
class TestPassed : TestResultMessage, ITestPassed
{
/// <summary>
/// Initializes a new instance of the <see cref="TestPassed"/> class.
/// </summary>
public TestPassed(ITest test, decimal executionTime, string output)
: base(test, executionTime, output) {
Console.WriteLine("Execution time was an awesome " + executionTime);
}
}
I'm having trouble registering this one, or if i'm even registering it right. As far as the examples go, I have found the actual message sinks but also found the actual test status data which i'm not exactly sure how to use.
I haven't worked with TestNG, but I did some quick reading and I think I see what you're after.
To demonstrate, I've created a very basic proof-of-concept implementation of the xUnit [IMessageSink] interface (https://github.com/xunit/abstractions.xunit/blob/master/src/xunit.abstractions/Messages/BaseInterfaces/IMessageSink.cs).
public class MyMessageSink : IMessageSink
{
public bool OnMessage(IMessageSinkMessage message)
{
// Do what you want to in response to events here.
//
// Each event has a corresponding implementation of IMessageSinkMessage.
// See examples here: https://github.com/xunit/abstractions.xunit/tree/master/src/xunit.abstractions/Messages
if (message is ITestPassed)
{
// Beware that this message won't actually appear in the Visual Studio Test Output console.
// It's just here as an example. You can set a breakpoint to see that the line is hit.
Console.WriteLine("Execution time was an awesome " + ((ITestPassed)message).ExecutionTime);
}
// Return `false` if you want to interrupt test execution.
return true;
}
}
The sink is then registered via an IRunnerReporter:
public class MyRunnerReporter : IRunnerReporter
{
public string Description => "My custom runner reporter";
// Hard-coding `true` means this reporter will always be enabled.
//
// You can also implement logic to conditional enable/disable the reporter.
// Most reporters based this decision on an environment variable.
// Eg: https://github.com/xunit/xunit/blob/cbf28f6d911747fc2bcd64b6f57663aecac91a4c/src/xunit.runner.reporters/TeamCityReporter.cs#L11
public bool IsEnvironmentallyEnabled => true;
public string RunnerSwitch => "mycustomrunnerreporter";
public IMessageSink CreateMessageHandler(IRunnerLogger logger)
{
return new MyMessageSink();
}
}
To use my example code, just copy the classes into your test project (you'll also need to add a reference to the xunit.runner.utility NuGet package). The xUnit framework will automagically discover the IRunnerReporter--no need to explicitly register anything.
If this seems like it's headed in the right direction, you can find a lot more info in the xUnit source code. All of the interfaces involved are well-documented. There are a few existing implementations in the xunit.runner.reporters namespace. AssemblyRunner.cs also demonstrates one possible method for dispatching the different event types to individual handlers.
Edit 1
I've updated the implementation of MyMessageSink (above) to demonstrate how you might listen for an ITestPassed message. I also updated the link embedded in that code snippet--the previous link was to implementations, but we should really use these abstractions.
The if (message is IMessageType) pattern is pretty crude, and won't scale well if you want to listen for many different message types. Since I don't know your needs, I just went with the simplest thing that could possibly work--hopefully it's enough that you can improve/extend it to fit your needs.

Display custom warning at compile time related to method implementation in C#

In the current context we have two methods Start and Stop. These two methods are invoked from a function sequentially. There can be chances that a person invokes just Start() inside his method but forgets to invoke Stop(). e.g.
private void A()
{
Start();
//Buisness logic goes here
}
In this context when the code is compiled a warning or error needs to be displayed informing that for every Start() there should be a corresponding Stop(). Can somebody suggest ideas on how to go about implementing the same in C#?
The proper way of implementation would be
private void A()
{
Start();
//Buisness logic goes here
Stop();
}
I would suggest you change your pattern to take care of the Start and Stop without ever exposing it to the programmer.
Change your class implementing Start & Stop to implementing an Execute method instead and dont even expose the Start & Stop.
public class MyClass
{
private void Start(){} // old public method
private void Stop(){} // old public method
public void Execute(Action action)
{
Start();
action();
Stop();
}
}
Usage:
var impl = new MyClass();
impl.Execute(() => {
// do something in between start & stop
});
Evk gave a good hint, here is how I would do it in more detail:
Have a class (e.g. StartStop ) implement IDisposable
public class StartStop : IDisposable
{
public StartStop() { Start(); }
public void Dispose() { Stop(); }
protected void Start() { /*...*/ }
protected void Stop() { /*...*/ }
}
Make use of this class with using:
private void A()
{
using( var startStopCaller = new StartStopCaller() )
{
// Your code here
}
}
using will make sure Dispose() and subsequently Stop() will be called except for hard crashes.
This can be approached in many ways, with two primary directions:
If you're using the later versions of the .NET platform, and thus the Roslyn compiler (Defaults from VS2015 and onwards), you can look into writing a compiler plugin that checks this for you. Here are some resources:
Introduction to Scripting with the .NET Compiler Platform (Roslyn)
.NET Compiler Platform SDK
Probably a lot more out there, if you search for "Roslyn" or ".NET Compiler platform".
As some of the comments you got are pointing out, this could be fixed in your code and program design. This is most probably the "correct" way to approach this. Some examples:
Consider implementing IDisposable and use your class in a using statement - however, remember that stopping and disposing of an object might not be the same here. You should make an informed desicion about this with the knowledge you have about the inner workings of your program.
If you're calling these classes from elsewhere, you could let them implement an interface containing both your Start and Stop methods. And then let the calling class simply treat them as this interface, and make sure it calls both methods no matter which implementation it uses.
Re-architect your code to not depend upon running Start() and Stop() sequentially. This might require fundamental design changes to your program and how it works, but it might just be worth it. Both for readability and maintainability.

How to establish connect/disconnect event handlers in class that utilizes the blink1 HidLibrary?

I'm attempting to detect two events for this particular USB device (blink1): insert and remove
I've successfully enumerated the device(s) and can send commands, though I'm having a difficult time establishing the delegates and getting either event to trigger.
The HidLibrary.cs library contains two event handlers titled "InsertedEventHandler", "RemovedEventHandler" and the functions "DeviceEventMonitorInserted", "DeviceEventMonitorRemoved" which seem to be attached to an instance of the HidDeviceEventMonitor.cs class. I'm attempting to establish connect/disconnect/re-connect methods within the calling class where I utilize the HidLibrary class as:
using HidLibrary
...
private HidDevice hidDevice;
...
hidDevice.command(var1, var2, ..);
I feel this is a simple task, and I've established and worked with event handlers, routed events and delegates in the past to a limited degree in C# but I seem to be missing a crucial concept when dealing with this particular situation.
Update: In case anyone else comes across this when working with the blink1 HidLibrary, to enable the EventMonitor you must set hidDevice.MonitorDeviceEvents = true after calling OpenDevice() on the HidDevice instance. This isn't in any of the documentation and only became apparent after getting the event routing down.
I don't have any Blink1 devices, but after spending a few minutes with the code, I think this might work:
public static void Main()
{
HidDevice device;
// device declaration
device.Inserted += Device_Inserted;
device.Removed += Device_Removed;
}
private static void Device_Removed()
{
// Some stuff to do when device is removed
throw new NotImplementedException();
}
private static void Device_Inserted()
{
// Some stuff to do when device is inserted
throw new NotImplementedException();
}

Categories

Resources