I have an IObservable<byte[]> that I transform into an IObservable<XDocument> using some intermediate steps:
var observedXDocuments =
from b in observedBytes
// Lot of intermediate steps to transform byte arrays into XDocuments
select xDoc;
At some point in time, I'm interested in the observed XDocuments so I subscribe an IObserver<XDocument>. At a later point in time, I would like to subscribe another IObserver<XDocument> and dispose of the old one.
How can I do this in one atomic operation, without loosing any observed XDocument? I could do something like:
oldObserver.Dispose();
observedXDocuments.Subscribe(newObserver);
I'm worried though, that between these two calls, I could loose an XDocument. If I switch the two calls, it could happen that I receive the same XDocument twice.
I'd probably add a layer of indirection. Write a class called ExchangeableObserver, subscribe it to your observable, and keep it permanently subscribed. The job of ExchangeableObserver is to delegate everything to a given sub-observer. But the programmer is allowed to change the sub-observer being delegated to at any time. In my example I have an Exchange() method. Something like:
public class ExchangeableObserver<T> : IObserver<T> {
private IObserver<T> inner;
public ExchangeableObserver(IObserver<T> inner) {
this.inner=inner;
}
public IObserver<T> Exchange(IObserver<T> newInner) {
return Interlocked.Exchange(ref inner, newInner);
}
public void OnNext(T value) {
inner.OnNext(value);
}
public void OnCompleted() {
inner.OnCompleted();
}
public void OnError(Exception error) {
inner.OnError(error);
}
}
you can use a semaphore that makes shure that while IObservable<byte[]> prepares for IObservable<XDocument> no observer-change takes place.
pseudocode how this could be done (not testet)
System.Threading.ReaderWriterLockSlim criticalSection
= new System.Threading.ReaderWriterLockSlim(...);
... converting from `IObservable<byte[]>` to `IObservable<XDocument>`
criticalSection.EnterReadLock();
Call IObservable<XDocument>
criticalSection.ExitReadLock();
.... replacing IObservable<XDocument>
criticalSection.EnterWriteLock();
Call change IObservable<XDocument>
criticalSection.ExitWriteLock();
Edit: with Call IObservable<XDocument>
> What exactly do you mean with the line `Call IObservable<XDocument>`?
I interprete your sentense
> I have an `IObservable<byte[]>` that I transform
> into an `IObservable<XDocument>` using some intermediate steps...
that you have registered an eventhandler for IObservable<byte[]> that creates a XDocument from byte[] and then calls
something that triggers an event for IObservable<XDocument>.
Call IObservable<XDocument> means the code that triggers the followup-event
Related
This question already has an answer here:
Pass event from class C through class B to class A
(1 answer)
Closed 1 year ago.
Ok so here is my use case.
I have written an MMO server game engine, and the way I have it architected right now is mostly EDA. When the server receives a packet from a client, the core server publishes an event that other classes are subscribed to which carries the packet payload in the EventType e argument. The message has a header in the first bytes of the message, the first half of the byte carries bitwise information that determines which Class should pick up the message and do something with it, while the second half of the byte determines which method in the class needs to process the message. And the classes that shouldn't process anything just drops it.
This evaluation is done through a series of if statements on each class, first asking...if (headervalue != myexpectedheader) return; ... for clarity, it's actually a double if (lessthan) || (morethan) return; because the set of header values that could belong to me is a range, because the first half of the byte addresses the class while the second half of the byte addressed the method, So the class can't really evaluate "what's mine" but rather "what's not mine" in order to keep that if statement at the top of the conditions set because it's more likely NOT MINE, than it is mine. This works just fine as is. The class that evaluates the header and determines the payload is for it, does so flawlessly, and the ones that shouldn't .. do not. I do not need help with this part, it was just asked that I explain it for others to understand.
Because this is an MMO server expected to recevied, process and respond to potentially several 1000s of users sending potentially hundreds of packets per second during network intensive activities, my concern is having a large number of classes performing condition evals for EVERY message received from untold numbers of clients.
Compound this with the fact that it is highly likely that 90 to 95% of the messages received should probably be picked up by one or two of the classes. So a LOT of system time will be wasted on evaluating "not for me" by every class, but also especially since 90% of the messages probably will go to the most used class.
I therefore am trying to build a message router that will subscribe to the incoming message event on the core server Class, perform the "which Class" condition evals just once for each message, and publish new events post-evaluation so that only the one or two other classes that really need to consume the event can subscribe to that new event and eliminate the untold numbers of wasteful evaluations that result in essentially " if (not for me) return;"
The scope of the question is really summed below, what's written above is not in scope for the actual question, it's just an explanation of how the evaluations are being conducted, and why this use case makes the question relevant.
I have a Class A which has a primary event. That event will fire off very rapidly. I have a high number of Class C's which need to potentially receive the information from Class A event. However because I have a high number of Class C subscribers, I want to create a Class B middle man as an event router to reduce the number of direct subscribers (and thus system overhead) to Class A
I want Class B to subscribe to Class A, and Class Cs to subscribe to Class B, with the final result that the correct Class C has effectively picked up the event from Class A.
I have already written the logic to sort the events, but I don't know how to write that pass through event so that Class C subscriber consumes the Class A Event by listening to the Class B event.
I'm not sure I understand the problem correctly, but to start somewhere, here's an example of what I think you're asking for (see fiddle for a test run: https://dotnetfiddle.net/abEgV4):
public class Program
{
public static void Main()
{
var source = new ClassA();
var middleman = new ClassB(source);
var subscribers = Enumerable.Range(0, 10)
.Select(_ => new ClassC(middleman))
.ToArray();
Console.WriteLine("Fire 1!");
source.FireEvent();
Console.WriteLine("Fire 2!");
source.FireEvent();
Console.WriteLine("Fire 3!");
source.FireEvent();
Console.WriteLine("Fire 4!");
source.FireEvent();
Console.WriteLine("Fire 5!");
source.FireEvent();
}
}
class ClassA
{
public delegate void SomeAEventHandler(object sender, string msg);
public event SomeAEventHandler SomeAEvent;
public void FireEvent()
{
SomeAEvent?.Invoke(this, "Event A fired");
}
}
class ClassB
{
public event ClassA.SomeAEventHandler SomeAEvent;
private ClassA _eventSource;
public ClassB(ClassA eventSource)
{
_eventSource = eventSource;
eventSource.SomeAEvent += SomeAEventHappened;
}
private void SomeAEventHappened(object sender, string msg)
{
var rnd = new Random().Next(10);
if (rnd % 2 == 0)
{
// Instead of 'this' use 'sender' if needed
SomeAEvent?.Invoke(this, msg);
}
}
}
class ClassC
{
private readonly ClassB _myMiddleman;
public ClassC(ClassB middleman)
{
_myMiddleman = middleman;
middleman.SomeAEvent += SomeAEventHappened;
}
private void SomeAEventHappened(object sender, string msg)
{
Console.WriteLine("ClassC got an event!");
}
}
Does that cover the problem or can you elaborate on what's missing?
I know you don't understand the question title. Let me tell you the whole scenario.
I have a class named as Processor. Processor can get notifiable steps or send notification to other application API depending on some condition. Like as below:
Method: SendOrStartProcess(Operation operation)
Method Implementation:
If(operation.steps.any(o=>o.canProcess)){
_service.notify(operations); //This is fine
}
else{
var totalSteps = await _service.getAdjustableSteps(); //It returns the adjustable steps and will invoke event which is subscribed by another class named as GetAdjustableStepsEnd. It can be invoked immediately or after some time.
//Set totalSteps in operationsc.steps and save in database and that's it.
}
Now, I have another class named as "OperationHandler" which subscirbed the GetAdjustableStepsEnd event.
public OperationHandler(IUnityContainer container)
{
_agent.GetAdjustableStepsEnd += GetAdjustableStepsEnd ;
}
public async void GetAdjustableStepsEnd (object sender, GetAdjustableStepsEndEventArgs e)
{
// Here i will call again the above method _processor.SendOrStartProcess(e.Operations);
}
//Now the problem is if event invokes after some time then it is fine because meanwhile i set the status in database. But if it invoked just after the getAdjustableSteps then i call SendOrStartProcess again and it sends getAdjustableSteps again because record is not set in the database. How to overcome this situation. I can not put lock on it because this is used by many clients.
I am trying to get an event to trigger once the code resulting from the trigger of another event finished working. To me, this means that I have to trigger the second event just at the end of said code.
The first event, here, is directly taken from the Vimba Camera API I'm using, and it works perfectly fine. I read a few things on how to call an event properly (particularly the first anwer here), but I can't get my second event to run properly. I probably misunderstood something, but what ?
Here is a pseudo-code version of what I wrote :
public partial class Form1 : Form
{
public delegate void SecondEventHandler(int[] myData);
public event SecondEventHandler SomethingHappened;
//Doing a lot of things irrelevant here
myObj.OnFirstEvent += new Obj.OnFirstEventHandler(this.OnFirstEvent);
private void OnFirstEvent(Data data)
{
//Doing things, and preparing myData
SomethingHappened += new SecondEventHandler(HandleSomethingHappened);
}
void HandleSomethingHappened(int[] myData)
{
//Working with myData
}
}
If you want to raise methods attached to second event:
private void OnFirstEvent(Data data)
{
//Doing things, and preparing myData
var h = SomethingHappened;
if(h != null)
h(pass your int[] parameter)
}
Actually, the easiest yet the cleanest way to achive this is called continuation-passing-style. OnFirstEvent(Data data) should become OnFirstEvent(Data data, Action<int[]> continuator). Whenever it is not null, your code calls it.
However I do warn you: don't let it grow and spread all over your code. It's hard to debug and maintain from a long-term perspective. If you'd expect such an approach to be used extensively, then take a look in reactive extensions.
I'm using a switch as a state manager for my XNA game. The switch is a part of main update method, so it's run every frame. Sometimes I need to set a timer value and it should only be set once per method call. There are multiple methods that set the timer per case, so it can't use the current and previous state numbers to check if it's ok to overwrite previous time.
case "state 34": {
SetTime(theTime); // should run only once
// other things
if (TheTimeisRight(time)) // runs every call
{
SetTime(theTime); // should run only once
if (TheTimeisRight(time))
{ /* some methods */ }
}
break; }
How can I make this work, or is there a better way to do this without going outside the switch? (changing SetTime method is ok, but I wouldn't like to clutter up the switch with additional code)
Another method: Introduce a wrapper around the method you want to call:
public sealed class RunOnceAction
{
private readonly Action F;
private bool hasRun;
public RunOnceAction(Action f)
{
F = f;
}
public void run()
{
if (hasRun) return;
F();
hasRun = true;
}
}
Then create var setTimeOnce = new RunOnceAction(() => SetTime(theTime)); before the switch statement, and call there as setTimeOnce.run(). Adjust for parameters/return values as necessary.
If you don't want to mess with boolean variables ala hasSetTimeAlready, you can always introduce another state that calls the method, then proceeds to the original state.
Put the call outside the loop.
You might need a separate conditional statement to determine whether it should run at all, but that's got to be infinitely better than trying to use flags and/or various other smelly-code approaches to control repetitions of the call.
Edit:
here is what I mean by putting it in one place outside of the switch:
if (someCondition && someOtherCondition && yetAnotherCondition)
setTime(theTime); // just one call, in one place, gets executed once
switch(someValue)
{
case "state 34": {
//SetTime(theTime); // no longer necessary
// other things
if (TheTimeisRight(time)) // runs every call
{
//SetTime(theTime); // no longer necessary
if (TheTimeisRight(time))
{ /* some methods */ }
}
break;
...etc...
}
A word of advice: use an enumeration for your switch value rather than a string.
To be brutally honest, this is about as much as anyone can realistically help you with this without seeing a more complete code sample (I think the sample you gave us is somewhat contrived and not quite accurate to what you have?). Chances are that the best way to get round this problem is to deconstruct the switch statement and start again because either maintaining a state machine is not the best way to handle this situation or you need to introduce some other states.
I have resorted to using HashSet<int> to check if the current SetTime(time, num) method has not been called before with if (!hashSet.Contains(num)).
void SetTime(int time, int num)
{
if (!hashSet.Contains(num))
{
theTime = time;
hashSet.Add(num);
}
}
Sure doesn't look too cool, but works and it doesn't damage method call too much (visually), so the switch's readability is saved.
1) I'm working on a project and I saw this piece of code, I don't understand what is the point of the Monitor.Lock statement. Can someone explain what its trying to do?
2) the postscript underscroll in the parameter name is really annoying, anyone else seen this naming convention?
public class FieldsChangeableHelper<T> : IFieldsChangeable<T>
{
object _lock;
int _lockCount;
FieldChanges<T> _changes;
public FieldsChangeableHelper()
{
_lock = new object();
_lockCount = 0;
}
public void AddChange(T field_, object oldValue_)
{
if (_changes == null)
_changes = new FieldChanges<T>(field_, oldValue_);
else
_changes.AddChange(field_, oldValue_);
if (RaiseEvent(_changes))
_changes = null;
}
#region IFieldsChangeable Members
public void BeginUpdate()
{
if (System.Threading.Interlocked.Increment(ref _lockCount) == 1)
Monitor.Enter(_lock);
}
public void EndUpdate()
{
if (System.Threading.Interlocked.Decrement(ref _lockCount) == 0)
{
FieldChanges<T> changes = _changes;
_changes = null;
Monitor.Exit(_lock);
RaiseEvent(changes);
}
}
protected bool RaiseEvent(FieldChanges<T> changes_)
{
if (_lockCount == 0 && Changed != null && changes_ != null)
{
Changed(this, changes_);
return true;
}
return false;
}
public event FieldsChanged<T> Changed;
#endregion
}
Monitor.Lock locks the portion of code when multiple thread tries to execute the same piece in parallel. It is made to ensure that only 1 guy is altering/executing the context. Look at the MSDN.
Although its best practice that the locking object is always static, but in your case it is not. Which might pose some problem if your instantiating multiple objects on an open type.
Note one thing, in generics static on open T is different for different type, i.e static member in an Open Type class in your case is different for T i.e DateTime, string, etc.
In csharp, private members of a type are usually named with prefixed _
The way i read it: BeginUpdate() ensures that the current thread calling has exclusive access to the instance and that change events practically will be batched and raised once EndUpdate is called. The author wanted to deal with recursion by itself (e.g. calling BeginUpdate() on the same thread multiple times) and a mechanism to batch UpdateEvents untill after the lock has been released. Because, there is a potential deadlock when raising Events when you still have a lock on yourself. event subscribers might want to access your members and therefore have to lock the sender instance which is already locked.
The whole conditional locking is not required (if my analyses is correct ofcourse) since locks based on the Monitor class are recursive and counted.
There is another problem with the locking mechanism, that is: currently when one thread holds a lock. The second thread wont even wait for the lock but will simply continue without a lock since the lock is conditional! this seems like a big bug!
Regarding the naming convention. I use it myself for a way of differentiating privates from parameters and locals. Its a preference which many C# coding conventions recommend. This helps in a case like this:
void Method(int number)
{
// no need to refer to this since:
//this.number = number;
// can be replaced with
_number = number;
}