I am programming a game using the Unity Engine and I am currently running into the following problem:
I have a method that asynchronously returns his result using the parameters of a callback function. Pretty straightforward, it looks like this:
public void CalculateSomething( - PARAMETERS - , Action<float> callback)
I have to call this method in a loop for different parameters.
foreach(float f in manyFloats){
CalculateSomething(f, myCallback);
}
void myCallback(float f){
...compare this result value to the other values?...
}
Now I would like to compare the resulting floats, that come with the different callbacks. Let's just say I want to find the highest value among those floats. How do I do that?
I had the idea to store the results in an array field and just compare after it is fully filled, but I don't know how to check if all callbacks are done already.
Ideally I'd like to avoid polluting my class with a field like this, but it would be alright if there is no other way.
The CalculateSomethingfunction is part of a library, so I can't change it. Everything else is variable.
Here is the deal.
You got it right about creating the array and storing the values and compare them when all callbacks are done. Hence the problem is that you don't know when all the callbacks are returned. But you know how many callbacks are there based on count of your origin manyFloats variable. All you need to do is keep a counter and add it up every time a callback is returned. And check if it equals the count of manyFloats then you can do the comparison:
int count = 0;
void myCallback(float f)
{
... usual stuff
... then
if(count == manyFloats.Count)
{
// do the comparison
}
else
{
count ++;
}
}
Rather than using a callback based model you should use a Task based model. Have CalculateSomething return a Task<float> instead of having a callback. This allows you to use the TPL to compose these Task objects by writing code like:
var highestResult = (await Task.WhenAll(manyFloats.Select(CalculateSomething))).Max();
If you can't edit the method itself, then create your own wrapper that transforms the method into a task based version.
So, if we have no control over CalculateSomething function, we still can store max value and make comparison in our callback. Something like this:
void callbackFunction( float numb){
if (numb > maxNumb) //maxNumb is global
maxNumb = numb;
}
then you can use your foreach loop to go through your array. Just keep in mind that you would need to declare your maxValue global variable and make it initially equal to minimum value.
Even if you are not doing Min/Max comparison, and it is something more complicated, you still can do it in callback function. No need for arrays, because even with arrays if you can do it with single pass through array - you can do it in a callback function.
Related
I have a property, IList <IMyPlayer> Players {}, which syncs with the game server every time it is summoned. I need to know if it will update every increment when made limiting count in a for loop. The reason why is I'm worried a player may leave the game during this loop.
edit this is a single thread application.
public static IList <IMyPlayer> Players
{
get
{
playersField.Clear(); //GetPlayers() just adds without overwriting so list must be cleared every time.
if (Debugging == false)
{
MyAPIGateway.Multiplayer.Players.GetPlayers (playersField); //everytime the project needs to see all players, this will update. Little heavier on performance but its polymorphic.
}
return playersField.AsReadOnly();
}
}
for (int i = 0; i < AttendanceManager.Players.Count; i++)
{
if (AttendanceManager.Players[i].SteamUserId == MyAPIGateway.Multiplayer.MyId)
{
//do stuff
}
}
I can see several potential problems with your approach:
You add items while you are looping over it, but only loop until the original count is reached. So any added items are not accessed by the for loop
Your getter is doing more than a "normal" getter, which could mean performance problems if clients are not aware of that
using foreach would only call the getter once, which would behave differently that your for loop.
If you want to do this, I would instead make it a GetPlayers() function which makes it clearer that you are creating something as part of the method, and not just getting the current value of a property. If a client wants to reload the list each time they are stil lfree to do so, but it would be more obvious looking at the code.
For example:
for (int i = 0; i < AttendanceManager.GetPlayers().Count; i++)
{
if (AttendanceManager.GetPlayers()[i].SteamUserId == MyAPIGateway.Multiplayer.MyId)
look much more dodgy than a standard property getter.
I would most certainly not do this.
Every time you use your property it is going to call an API. That is going to be terrible for performance. Also it could be quite easy for your property to be called multiple times, even if you don't think it will be. One example I can think of is serialization, or if you are using this as an argument to say an MVC or Web API controller method.
This is what is commonly referred to as a side-effect, which is something you want to avoid in a getter at all costs.
I'm just starting to learn Observable and all it variations and run into some strange problem. Here it is:
I have a WCF service declaration (after 'Add Service reference' process):
public IAsyncResult ReceiveAllUsersAsync(AsyncCallback Callback, object State)
{
// Do some work
}
and here the closing one:
public IObservable<User> EndReceiveAllUsers(IAsyncResult AsyncResultHandler)
{
// Do some work (actuall y it's a: return AsyncResultHandler.EndInvoke();
// return IObservable<User>
}
as you can see the EndReceiveAllUsers return collection of User's
next I run an RX like so:
// This will not owrk
Func<IObservable<User>> callWcfService = Observable.FromAsyncPattern<IObservable<User>>(BeginReceiveAll, EndReceiveAll);
// Actuall Func<> signature is:
Func<IObservable< IObservable<User> >> callWcfService = Observable.FromAsyncPattern<IObservable<User>>(BeginReceiveAll, EndReceiveAll);
but the problem is that whatever returned from Observable.FromAsyncPattern is IObservable<> of IObservable<User>. Actually it return IObservable< IObservable<User> >. How I could return just one result of IObservable<User> and not the collection of result
It really depends on the behavior you want, but to answer your question directly, you can simply concatenate each sequence of users after the completion of the last one:
IObservable<IObservable<User>> tooMuch = callWcfService();
IObservable<User> justRight = tooMuch.Concat();
Edit:
Observable abstracts the multiple calls to ReceiveAllUsersAsync/EndReceiveAllUsers for you, so each time you get a whole IEnumerable<User>, it's produced as a whole by Observable. So if you want to produce the Users one by one, you need to switch to functions that produce users one at a time. ReceiveAllUsersAsync is not the function you need, as it waits until all the users are obtained, and gives them all back in a pack.
The one thing you can do is to convert the obtained IEnumerable<User> to IObservable<User>, but this will again behave in such a way: (1) get all the users under the hood, (2) produce all of them without pause -- which is not what you expect from a decent IObservable<>.
Old answer, for reference:
Looking at http://msdn.microsoft.com/en-us/library/hh212031%28v=vs.103%29.aspx:
public static Func<IObservable<TResult>> FromAsyncPattern<TResult>(
Func<AsyncCallback, Object, IAsyncResult> begin,
Func<IAsyncResult, TResult> end
)
So you perhaps just need Observable.FromAsyncPattern<User>, as User is your TResult.
Is there a convention for whether or not to use a property to calculate a value on call? For instance if my class contains a list of integers and I have a property Average, the average will possibly change when an integer is added/removed/modified from the list, does doing something like this:
private int? _ave = null;
public int Average
{
get
{
if (_ave == null )
{
double accum = 0;
foreach (int i in myList)
{
accum += i;
}
_ave = accum / myList.Count;
return (int)_ave;
}
else
{
return (int)_ave;
}
}
}
where _ave is set to null if myList is modified in a way that may change the average...
Have any conventional advantage/disadvantage over a method call to average?
I am basically just wondering what the conventions are for this, as I am creating a class that has specific properties that may only be calculated once. I like the idea of the classes that access these properties to be able to access the property vs. a method (as it seems more readable IMO, to treat something like average as a property rather than a method), but I can see where this might get convoluted, especially in making sure that _ave is set to null appropriately.
The conventions are:
If the call is going to take significantly more time than simply reading a field and copying the value in it, make it a method. Properties should be fast.
If the member represents an action or an ability of the class, make it a method.
If the call to the getter mutates state, make it a method. Properties are invoked automatically in the debugger, and it is extremely confusing to have the debugger introducing mutations in your program as you debug it.
If the call is not robust in the face of being called at unusual times then make it a method. Properties need to continue to work when in used in constructors and finalizers, for example. Again, think about the debugger; if you are debugging a constructor then it should be OK for you to examine a property in the debugger even if it has not actually been initialized yet.
If the call can fail then make it a method. Properties should not throw exceptions.
In your specific case, it is borderline. You are performing a potentially lengthy operation the first time and then caching the result, so the amortized time is likely to be very fast even if the worst-case time is slow. You are mutating state, but again, in quite a non-destructive way. It seems like you could characterize it as a property of a set rather than an "ability" of the set. I would personally be inclined to make this a method but I would not push back very hard if you had a good reason to make it a property.
Regarding your specific implementation: I would be much more inclined to use a 64 bit integer as the accumulator rather than a 64 bit double; the double only has 53 bits of integer precision compared to the 64 bits of a long.
Microsoft's recommendation to using methods:
Use method
If calling has side effects
If it returns different values each calls
If it takes long time to call
If operation requires parameters (except indexers)
Use property if calculated value is attribute of object.
In your case I think property with implicit lazy calculation would be good choice.
Yes there is... a get accessor should not in any way modify the state of the object. The returned value could be calculated of course, and you might have a ton of code in there. But simply accessing a value should not affect the state of the containing instance at all.
In this particular case, why not calculate everything upon construction of the class instance instead? Or provide a dedicated method to force the class to do so.
Now I suppose there might be very specific situations where that sort of behavior is OK. This might be one of those. But without seeing the rest of the code (and the way it is used), it's impossible to tell.
I have an abstract class which runs a fairly computationally intensive series of static functions inside several nested loops.
In a small number of these loops, I need to obtain a list of dates which are stored in a comma-separated string in a .settings file. I then parse them into DateTimes and use them.
The issue is, I'm re-parsing these strings over and over again, and this is using up quite a bit of CPU time (obviously). Profiling shows that 20% of the core algorithm is wasted on these operations. If I could somehow cache these in a place accessible by the static functions then it would save me a lot of processing time.
The simplest option would be to parse the list of DateTimes at the very start of computation, and then pass that list to each of the sub-functions. This would certainly cut down on CPU work, but it would mean that the sub-functions would need to accept this list when called outside the core algorithm. It doesn't make intuitive sense why a list of DateTimes would be needed when calling one of the parent static functions.
Another thing to fix it would be to make the class not abstract, and the functions non-static, and store the list of dates, etc, in variables for each of the functions to access. The reason I wanted to have it abstract with static functions is because I didn't want to have to instantiate the class every time I wanted to manually call one of the sub-functions.
Ideally, what I would like to do is to parse the list once and store it somewhere in memory. Then, when I do a subsequent iteration, I can somehow check to see if it's not null, then I can use it. If it's null (probably because I'm in the first iteration), then I know I need to parse it.
I was thinking I could have a .settings file which has the list in it. I would never save the settings file to disk, but it would basically allow for storage between static calls.
I know this is all very messy - I'm just trying to avoid re-writing a thousand lines of static code if feasible.
If you all think it's a terrible idea then I will raise my white flag and re-write it all.
If the dates are read-only then it's pretty straightforward - declare a static property on a class which loads the values if they don't exist and stores them in a static variable - something like this:
public class DateList
{
private static List<DateTime> mydates = null; // new List<DateTime>(); haha, oops
public static List<DateTime> Current {
get {
if(mydates == null)
{
lock(typeof(DateList)) {
if(mydates == null) {
mydates = LoadDates();
}
}
}
return mydates;
}
}
// thanks to Porges - if you're using .NET 4 then this is cleaner and achieves the same result:
private static Lazy<List<DateTime>> mydates2 = new Lazy<List<DateTime>>(() => LoadDates(), true);
public static List<DateTime> Current2
{
return mydates2.Value;
}
}
this example would then be accessed using:
var dates = DateList.Current
Be careful if the dates are not read-only - then you'll have to consider things in more detail.
Another thing to fix it would be to make the class not abstract, and the functions non-static, and store the list of dates, etc, in variables for each of the functions to access. The reason I wanted to have it abstract with static functions is because I didn't want to have to instantiate the class every time I wanted to manually call one of the sub-functions.
Do this. Classes exist in order to encapsulate state. If you store the cache somewhere static, you'll only make trouble for yourself if/when you want to add parallelism, or refactor code.
I'm not sure what you mean by the second part ("manually call"). Do you mean while testing?
I'm looking for a container that keeps all its items in order. I looked at SortedList, but that requires a separate key, and does not allow duplicate keys. I could also just use an unsorted container and explicitly sort it after each insert.
Usage:
Occasional insert
Frequent traversal in order
Ideally not working with keys separate from the actual object, using a compare function to sort.
Stable sorting for equivalent objects is desired, but not required.
Random access is not required.
I realize I can just build myself a balanced tree structure, I was just wondering if the framework already contains such a beast.
You might want to take a look at the Wintellect Power Collections. It is available on CodePlex and contains quite a few collections that are very helpful. The OrderedBag collection in the project is exactly what you are looking for. It essentially uses a red-black tree to provide a pretty efficient sort.
Just to make EBarr's comment as answer, there is SortedSet<T> since .NET 4.0. Of course it is a set, which means you cannot have duplicates.
If you just want to stick with the standard collections then the Sort(IComparer<>) function of the List<> class is one that often gets ignored. All you need to do is create a suitable Comparer<> for your objects. For example:
public class PositionDateComparer : IComparer<VehiclePosition>
{
public int Compare(VehiclePosition x, VehiclePosition y)
{
if (x.DateTime == DateTime.MinValue)
{
if (y.DateTime == DateTime.MinValue)
{
// If x is null and y is null, they're
// equal.
return 0;
}
// If x is null and y is not null, y
// is greater.
return -1;
}
// If x is not null...
//
if (y.DateTime == DateTime.MinValue)
// ...and y is null, x is greater.
{
return 1;
}
// ...and y is not null, compare the dates
//
if (x.DateTime == y.DateTime)
{
// x and y are equal
return 0;
}
if (x.DateTime > y.DateTime)
{
// x is greater
return 1;
}
// y is greater
return -1;
}
}
Then just perform a vehiclePositionsList.Sort(new PositionDateComparer()) whenever you want to sort the list before accessing it. I realise that this might not be as simple as a container which automatically sorts every time you add a new object, but for many (like me!) this might be enough to do the job successfully without requiring any additional libraries.
I would extend your own list class that, as you mentioned, simply sorts after every insert. Since your inserts are infrequent the performance hit would be minimal, and sorting a nearly sorted list is quick, in any case. Extend the Generic List and override the Add method to sort immediately. If performance becomes an issue you can insert in place to save some time. Furthermore you can queue up your inserts to do a single traversal insertion for all the values you want to insert.
As I mentioned earlier today here, the C5 Generic Collection Library has the proper container for you.
If the key is also an attribute of the object, you might try the System.Collections.ObjectModel.KeyedCollection<TKey, TItem>. It's an abstract class, but if your key is just a property of the item then it's real simple to derive from.
Here's an old trick I used way back in VB6 to sort things alphabetically: Use a System.Windows.Forms ListBox object, and set its "Sorted" property to true. In C#, you can insert any object into the listbox, and it will sort the object alphabetically by its ToString() value:
for a class module:
using System.Windows.Forms;
static void Main(string[] args)
{
ListBox sortedList = new ListBox();
sortedList.Sorted = true;
sortedList.Items.Add("foo");
sortedList.Items.Add("bar");
sortedList.Items.Add(true);
sortedList.Items.Add(432);
foreach (object o in sortedList.Items)
{
Console.WriteLine(o);
}
Console.ReadKey();
}
This will display:
432
bar
foo
True