Iam writing an app that shows a list of the remaining time a user has on a course.
I want the list to dynamically update every second so the user has the full overview.
public class ReservationCustomerList : INotifyPropertyChanged
{
public int UnitsLeft { get; set; }
public DateTime? OnCircuitSince { get; set; }
public TimeSpan? TimeLeftDate
{
get
{
if (OnCircuitSince.HasValue)
return TimeSpan.FromSeconds((OnCircuitSince.Value - DateTime.Now).TotalSeconds - UnitsLeft);
return TimeSpan.FromSeconds(UnitsLeft);
}
}
private void FireEverySecond()
{
PropertyChanged.Fire(this, x => x.TimeLeftDate);
}
}
As you can see above the idea is that the model knows when the customer entered the circuit and the time the have left.
As you can see iam thinking of using the INotifyPropertyChanged interface and then actually having a timer on every viewmodel.
However this is my concern. Adding a Timer on every viewmodel seems very bloated, is this really the best way to achieve this ?
Second concern is that if the timer is never stopped wouldn't this result in a memory leak since the timer would never stop and keep the viewmodel alive ?
If this is the case my Viewmodel would also need to implement IDisposable and i would need to remember to run through all viewmodels and dispose them to make sure that these are garbage collected. Are my concerns correct ?
Thanks.
Yes i was thinking of having a timer service to prevent having multiple timers, however having to manually unregister would surely at some point introduce memoery leaks.
So the idea with Weak Events is great.
Iam thinking of doing it something like this:
public class TimerService
{
static Timer Timer;
static FastSmartWeakEvent<EventHandler> _secondEvent = new FastSmartWeakEvent<EventHandler>();
static FastSmartWeakEvent<EventHandler> _minuteEvent = new FastSmartWeakEvent<EventHandler>();
static DateTime LastTime;
public static event EventHandler SecondEvent
{
add { _secondEvent.Add(value); }
remove { _secondEvent.Remove(value); }
}
public static event EventHandler MinuteEvent
{
add { _minuteEvent.Add(value); }
remove { _minuteEvent.Remove(value); }
}
static TimerService()
{
Timer = new Timer(TimerFire, null, 1000, 1000);
}
static void TimerFire(object state)
{
_secondEvent.Raise(null, EventArgs.Empty);
if (LastTime.Minute != DateTime.Now.Minute)
_minuteEvent.Raise(null, EventArgs.Empty);
LastTime = DateTime.Now;
}
}
Do you have any comments ?
I Know i could use a singleton GetInstance (or IoC) however this would just make it more inconvinient to use.
Iam using the WeakEvent implementation that Daniel Grunwald wrote on codeproject. (it gives a very clean class and not much overhead).
http://www.codeproject.com/KB/cs/WeakEvents.aspx
You could have a timer service with a private timer and a public event, that notifies all the viewmodels every second.
Regarding the memory issues, you could register your viewmodel with the timer service when your page is navigated (OnNavigatedTo) and unregister it when the view is closed (OnNavigatedFrom). This way the viewmodels wouldn't have any reference with the timer service when they go out of scope, and they would be garbage collected properly.
Related
I'm reading values from a certain process memory. Let's say that I fetch them in the following way:
var foo = memoryService.GetFoo();
var bar = memoryService.GetBar();
Since it doesn't exist any events for memory changes, I would like to create custom events using polling (if you don't have any other suggestions).
Since I don't know when the values might change, the polling interval has to be set to a suitable value. I don't know how to actually write this, but something like this might do (not sure if it compiles):
public class MemoryChange : INotifyPropertyChanged
{
private Timer _timer;
public SomethingChanged(double polingInterval)
{
_timer = new Timer();
_timer.AutoReset = false;
_timer.Interval = polingInterval;
_timer.Elapsed += timer_Elapsed;
_timer.Start();
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
}
}
Do I need to create one class that implements INotifyPropertyChanged for each value (foo and bar in this case)?
Is there any way to make it run on a non blocking thread (using a Task perhaps?)?
Do I have to use polling to make this work?
Any input is much appreciated!
If you have access to your MemoryService from your main view model, then you could define a simple delegate to solve your problem.
In your MemoryService, define the delegate and related property:
public delegate void DataUpdate(object someData);
public DataUpdate OnDataUpdate { get; set; }
In the parent view model, attach a handler for the delegate:
MemoryService memoryService = new MemoryService();
memoryService.OnDataUpdate += MemoryService_OnDataUpdate;
Back in MemoryService when the data is ready:
var foo = memoryService.GetFoo();
// Always check for null
if (OnDataUpdate != null) OnDataUpdate(foo);
Now in the parent view model:
public void MemoryService_OnDataUpdate(object someData)
{
// Do something with the new data here
}
You can find out more about using delegate objects from the Delegates (C# Programming Guide) page on MSDN.
I am not sure in what context you will be using your memory service though I will give it a try to answer your quesiton.
Yes, you will have to implement INotifyPropertyChanged in every class.
Yes there is a way, Google knows it.
You can use polling or you could listen to PropertyChanged event. That would be the callback approach where you get notified when a changes happened.
I am trying out the ExcelAsyncUtil.Observe function. I made the following code that shows a running clock in Excel. It works fine but I am not sure what I am doing. Two questions:
Should I add functionality for observer.OnCompleted() and observer.OnError()? What does these calls do?
What should I do in the IDisposible class? Why is it there?
Here is my sample code:
[ExcelFunction]
public static object MyExcelTicker()
{
return ExcelAsyncUtil.Observe("MyExcelTicker", new object[] { }, TickerFunction());
}
public static ExcelObservableSource TickerFunction()
{
ExcelObservableSource source = new ExcelObservableSource(() => new TickerObservable());
return source;
}
public class TickerObservable : IExcelObservable
{
public IDisposable Subscribe(IExcelObserver observer)
{
var timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Start();
// What about observer.OnCompleted() and observer.OnError()?
return new TickerDisposable();
}
}
public class TickerDisposable : IDisposable
{
public void Dispose()
{
// What to do here?
}
}
It has been a while and at least one thing is still left not covered, so let me add to what Govert said.
You've asked:
public class TickerDisposable : IDisposable
{
public void Dispose()
{
// What to do here?
}
}
Let's summarize:
For each new subscriber to your clock-ticker, a Subscribe will be called on the TickerObservable. Therefore, for each subscriber, your code will create a new System.Timers.Timer and a new timer.Elapsed event handler - to get your intended effect. And this is actually all that you need to get your effect.
However, you are also required to return an IDisposable, therefore you've created a dummy TickerDisposable solely for that purpose, and you are not sure what it is for.
Answer:
The IDisposable that the library requires you to return from the Subscribe is there just to allow you to cleanup after your glitter stops shining. Timers are a "system thing". Once you create them and start them, they run. After an hour they cannot be GC'ed, because they are meant to be run until you stop them. Surely, you've +='ed an event hander, the observer (if weakly-reference'd) might be already dead, but your timer does not know! You must stop it at some point.
Hence, IDisposable-related pattern, borrowed from RX: whatever heavy or long-living you allocate, reserve, build, etc in the Subscribe method, put some note about it into that (yours!) IDisposable. Then, when the observer unsubscribes, your IDisposable will get cleaned too, and your custom Dispose method will be run, that will be able to look at your IDiposable's contents and .. cleanup the garbage, or rather, unlock it, so the GC can flush them.
Completing your example:
public class TickerObservable : IExcelObservable
{
public IDisposable Subscribe(IExcelObserver observer)
{
var timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Start();
return new TickerDisposable(timer);
}
}
public class TickerDisposable : IDisposable
{
private Timer ticky;
public TickerDisposable(Timer timer)
{
ticky = timer;
}
public void Dispose()
{
if(ticky != null)
ticky.Dispose(); // or Stop, or etc..
}
}
The above example is actually most-obvious usage of the returned IDisposable. However, you can use it for any register-unregister notification. For example, with single shared timer, it might look like this:
public class TickerObservable : IExcelObservable
{
private static Timer timer = ..... ; // assume it is up & running & shared
public IDisposable Subscribe(IExcelObserver observer)
{
ElapsedEventHander hd = (s, e) => observer.OnNext(DateTime.Now.ToString());
timer.Elapsed += hd;
return new TickerDisposable(timer, hd);
}
}
public class TickerDisposable : IDisposable
{
private Timer ticky;
private ElapsedEventHander handler;
public TickerDisposable(Timer timer, ElapsedEventHander hd)
{
ticky = timer;
handler = hd;
}
public void Dispose()
{
if(ticky != null && handler != null)
ticky.Elapsed -= handler;
}
}
And now you are perfectly sure that no dead-handlers are lingering at the long-living-shared-timer. (of course the cleanup of the timer is missing here, but that's another thing..). Probably you already got the idea, so, have fun!
The IExcelObserver interface matches the semantics of the IObserver interface from the Reactive Extensions library (http://msdn.microsoft.com/en-us/library/dd783449.aspx).
You function can call OnNext zero or more times, and then call OnError if an error occurs, or OnCompleted if no further events will be raised. Excel-DNA will handle OnError as it would an exception thrown by a regular UDF, and will return #VALUE to the cell or process the exception via the registered UnhandledExceptionHandler. OnCompleted is not so useful in the Excel context - it just indicates that no further values will be raised.
For your example, error don't seem to be a problem, and there is no end to the stream of events, so you need never call OnError or OnCompleted.
The Excel-DNA infrastructure will call the IDisposable.Dispose when the observable is no longer hooked up to a cell formula. For example, if the formula with the MyExcelTicker() call is deleted from the cell. You can use this as a notification to clean up any back-end resources, or ignore the notification if you're not interested.
Consider this code:
class GameEventsManager
{
public void StartGameEvent(GameEvent TheGameEvent)
{
SubscribeToGameEvent(TheGameEvent);
TheGameEvent.Begin();
UnsubscribeToGameEvent(TheGameEvent);
}
private void SubscribeToGameEvent(GameEvent TheGameEvent)
{
TheGameEvent.OnPlaySound += OnPlaySound;
TheGameEvent.OnShowWrittenItem += OnShowWrittenItem;
...
}
private void UnsubscribeToGameEvent(GameEvent TheGameEvent)
{
TheGameEvent.OnPlaySound -= OnPlaySound;
TheGameEvent.OnShowWrittenItem -= OnShowWrittenItem;
...
}
}
A GameEvent is a class that basically does this: when Begin() gets called, it raises events that get passed to the GameEventManager, so that it may "make" the appropriate changes to the game environment (this is by further propagating the events to the objects that are responsible for executing each particular instruction, like in the Observer pattern).
Now take into consideration that all of my InventoryItems (can trigger events, such as OnConsume, OnUse) are static fields in their particular classes. Although this may seem a bit rough around the edges, I feel that being able to do:
AddItem(WrittenItems.NoteFromKing) //NoteFromKing is a static field in WrittenItems
makes things a lot simpler, and it's a welcome sight considering I'm working on a quite complex game.
This, however, makes it very hard for me to list ALL of the game's items somewhere, in case this would be needed. Which brings us to my question:
A LevelManager, that manages things such as when the player interacts with a particular item in the level, tells the GameEventsManager to run a particular GameEvent, if required. The GameEventsManager then subscribes to the GameEvent, starts it, and then unsubscribes. Should I expect to see noticeable performance issues while following this subscribe/run/unsubscribe pattern? In the end, the manager might subscribe/unsubscribe to about 20 events inside GameEvent.
In case the subscribe/unsubscribe mechanism is slow, I could make a single subscribe process that runs at game initialization, but that would force me to build an extra structure, to list all of the items.
So, in short, I'd like to know if I should be expecting considerable slowdowns from this kind of implementation. Or more exactly, if subscribing to about 20 events, and then unsubscribing from them is considerably slow.
Language is C#, using .NET 2.0 subset under Unity 4.
This, however, makes it very hard for me to list ALL of the game's items somewhere
Why so? You could create an ItemManager (which is a singleton):
public class ItemManager
{
private static volatile ItemManager _instance;
private static object syncRoot = new Object();
private ObservableCollection<ItemBase> _registeredItems = new ObservableCollection<ItemBase>();
private ItemManager()
{
}
public ItemManager Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new ItemManager();
}
}
return instance;
}
}
public void RegisterItem(ItemBase item)
{
_registeredItems.Add(item);
// Do some stuff here, subscribe events, etc.
}
public void UnregisterItem(item)
{
// Do some stuff here, unregister events, etc.
_registeredItems.Remove(item)
}
}
Afterwards you make all item classes derive from a class called "ItemBase". And in ItemBases Constructor you call this:
ItemManager.Instance.RegisterItem(this);
So you don't have to add every single item manually. For more information about the singleton pattern, take a look here: http://msdn.microsoft.com/en-us/library/ff650316.aspx.
A little benefit of this is also, that you can implement a general communication between the GameManager and the ItemManager.
I'm working on a winforms application that is very complicated, and has massive callback chains being passed around all over the place.
As an example loosely based on this code, there could be a "Manager" class, that spawns a class "SetUpWorkerThreads" class, which creates a "HandleWorker" thread for say 10 workers.
The worker thread needs to call back to the manager class on occasion, to achieve this the code looks like this:
public class Manager
{
public delegate void SomethingHappenedHandler();
private void Init()
{
var x = new SetUpWorkerThreads(SomethingHappened);
}
private void SomethingHappened()
{
// Handle something happened
}
}
public class SetUpWorkerThreads
{
private readonly Manager.SomethingHappenedHandler _somethingHappened;
public SetUpWorkerThreads(Manager.SomethingHappenedHandler somethingHappened)
{
_somethingHappened = somethingHappened;
}
public void SetupTheThreads()
{
// Contrived!
for (int x=0; x<10; x++)
{
var worker = new Worker(_somethingHappened);
new Thread(worker.DoingSomething).Start();
}
}
}
public class Worker
{
private readonly Manager.SomethingHappenedHandler _somethingHappened;
public Worker(Manager.SomethingHappenedHandler somethingHappened)
{
_somethingHappened = somethingHappened;
}
public void DoingSomething()
{
// ... Do Something
_somethingHappened();
}
}
In reality, there can be many more classes involved, each passing around a mass of callbacks for various things. I realise that poor class/application design is playing a part in this, but are there better ways to go about handling these interactions between classes, specifically in winforms apps, and when a lot of threading is going on?
I can't see that the threading makes it more or less problematic.
One alternative is to use events instead of callbacks, but that won't break up the long chains and will give you an unsubscribing hell too.
One possible approach is to create an object responsible for handling all the events. Either as a singleton or as a single object that you pass to all your threads (instead of the callbacks). Then you can have a simple interface on the EventRouter object to raise events from the threads. You can then subscribe to events on the EventRouter where you need to handle "something happened".
Edit
Something the GoF pattern Mediator but with a publisher-subscriber twist.
I've been trying to identify some performance issues with our ASP.NET Web application. It's an online application, used by multiple users(10+). Just a quick overview: The applcation uses a combination of web forms, MVC Pages, web services etc... When multiple users connects to the app, it seems to become really slow. After investigating the memory, it seems as if the application is using A LOT of memory and that is slowing down the machine, which indicates unmanaged resources not being disposed of. I installed ANTS, and then captured a few applications on the system. It turns out a lot of the memory is used by unmanaged resources: http://tinypic.com/r/154ujra/7
This is the first time I've been profiling memory. ANTS profiler indicates that one of my classes (RULE) has a high number of live instances: http://tinypic.com/r/1264ltu/7 (Which doesn't seem to be freed up by the GC)
After drilling down into class level, http://tinypic.com/r/2r3v6nq/7, it displays a warning that the class isn't released from memory, and this could be because of an event handler not being unregistered. Now that class does contain an event handler instance, so could it be that?
public class Rule
{
public event EventHandler deleted;
public void Delete()
{
if (baseQuestionnaire.basePortfolio.mode != Mode.Admin)
{
throw new Exception("Rules can only be deleted in Admin mode");
}
else
{
// Delete the rule from the database
if (id != -1)
{
string delete = "DELETE FROM tb" + DataManager.dbPrefix + "_QuestionRule WHERE QuestionRuleId = " + id.ToString();
DataManager.execute(delete);
}
// Raise a deleted event
if (deleted != null)
deleted(this, new EventArgs());
}
}
}
Event is then assigned in another class like this, but never unregistered
public class Option : IComparable
{
public void AddRule(Rule newRule)
{
newRule.deleted += new EventHandler(newRule_deleted);
allRules.Add(newRule);
}
............................
}
Hmm.. I see that the eventhandler 'deleted' is a public one. So my guess is that the Rule object is created first and then the Rule.deleted is assigned an eventhandler. If this is the case then as you suspected, the eventhandler is probably the cause of Rule objects not being garbage collected.
EDIT:
Maybe you could try something like this:
public class Option : IComparable, IDisposable
{
private Rule newRule;
private EventHandler newRuleDeletedEventHandler;
public void AddRule(Rule newRule)
{
this.newRule = newRule;
newRuleDeletedEventHandler = new EventHandler(newRule_deleted);
newRule.deleted += newRuleDeletedEventHandler;
allRules.Add(newRule);
}
public override void dispose()
{
newRule.deleted -= newRuleDeletedEventHandler;
}
}