Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have a method that takes around 200ms to run and would therefor like to cache the result. This result will be used frequently, but it never changes.
I'm not entirely sure what the best solution would be for this, should I put this to a property or a get method?
As an example:
1
private string _result;
public string Result => _result ?? (_result = GetSlowResult());
2
private string _result;
public string GetResult() => _result ?? (_result = GetSlowResult());
Personally, from a property I typically expect it to be available "now" rather than "later" but with a Get method I expect the result to always retrieve a fresh GetSlowResult rather than using a cached value. I could change the method name to GetCachedResult but I'm not sold on that either as then it would seem you need to have called a GetResult method first.
Are there any guidelines to this? What do you prefer?
I would recommend you to use the Lazy<T> class. It causes you to pass a factory that talks about how to create that object, and after that, it is created only the first time you ask for it, and then uses the same reference(cached value).
Here's how it would look:
Lazy<T> Result = new Lazy<T>(GetSlowResult); //T is your type
Then, to use the result, just get her property Value:
T myResult = Result.Value;
You can see more about this in the official dotnet docs.
I would do this with read-only property and a method that fills the property.
If you know that result will be needed, you can load it at the begining - during startup of a service, activation ov view etc.
I mostly use ReactiveUI in WPF apps, so it would look like that:
// ViewModel constructor
GetResult = ReactiveCommand.CreateFromTask(async () => _model.GetResultAsync()); // notice that method is async
// there is also overload with CancelationToken
_result = GetResult.Retry(3).ToProperty(this, x => x.Result); // we can retry few times and we get change notification
GetResult.Subscribe(result =>{
// do something as soon as the result is loaded
});
GetResult.ThrownExceptions.Subscribe( errorHandler);
// ViewModel properties
private ObservableAsProperetyHelper<ResultType> _result;
public ResultType Result => _result.Value;
// view constructor
this.WhenActivated(d =>{ // d is CompositeDisposable for cleanup
ViewModel.GetResult.Execute().Subscribe().DisposeWith(d); // cancel command if the view is deactivated before it's finished
});
That way you can make async call in proper moment and store the result for later. You can also easily refresh the result - that becomes dirty when using lazy properties alone.
On another plus side, you can easily create loading spinner:
_isBusy = GetResult.IsExecuting.ToProperty(this, x => x.IsBusy);
I followed this pattern in a always-on windows service running custom HTTP server in the background. You can await GetResult.Execute() if you want to enforce loading at a particular moment.
In my practice, this pattern shows very little shortcomings - main one is boilerplate code, but with proper tools it can be written really fast.
If you are creating some service type app, console or whatever, MVVM pattern is still very usefull, you just don't do views.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have simple scenario where I started to repeat same code multiple times, so I decided to move it in a private method, depending on a if/else it's being edited and my variables that are listed below might overwrite it's value which is perfectly fine:
ProductResponse identificationResults = new ProductResponse(); // I understand this assignment gets overridden in private method below but that is goal
long? productIdentificationRecordId = null; // I understand this assignment gets overridden in private method below but that is goal
I'm invoking my method on a few places in a code that's reason why I created private method to avoid code repetition in same file:
await SetProductStatusAndPerformDbActions(productCompany, userId );
private async Task SetProductStatusAndPerformDbActions(Company productCompany, long userId, ProductType productType, ProductStatus status, long? productIdentificationRecordId, ProductResponse identificationResults, CancellationToken cancellationToken)
{
status = GetCompanyProductStatus(productCompany.Id, identificationResults);
productIdentificationRecordId = await PerformDbAction(status, productType, userId, cancellationToken); // underlined this code
identificationResults = await IdentifyCompanyProduct(productCompany, cancellationToken); // underlined this code
}
Visual Studio says 'Remove this useless assignment to a local variable
productIdentificationRecordId'
Visual Studio says 'Remove this useless assignment to a local variable
identificationResults'
I understand this assignments gets overridden in private method below but that is point of private method because I want to use for example productIdentificationRecordId and its new value right after I call this private method because goal of private method is to modify it and that is it..
I'm not using vars which might cause this warning so I don't know what to do here.
How this could be written to avoid this scenarios ?
Edit:
Added screenshot from the private method, variables are grayed as they are not used:
Because these parameters are not being passed by reference, setting them to any value will only change the value of the parameter variables local to your helper method: it will not impact the values that were passed in to those parameters.
Since you don't use the new values you're assigning to those parameters inside the method, Visual Studio is smart enough to recognize that setting values to them has no effect. It's warning you about that, which is good because in this case you might think your code is doing something that it's not really doing.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am working on a azure function that makes dependency injection of a object, and I would like to know what I can do to it's create the instance just once in the constructor (when I deploy the function to production) and at the others requests to the functions reuse the first instance created.
I made a injection dependency of the object that I want to reuse but it don't worked.
There is no "function scope" variable in C# like there is in Native C++. But there is a bunch of similar constructs you can use:
Make a property with Public get but private Set. That way only class code (like the constructor) can set values. You see this pattern used abundantly all over the .NET Framework. However it does not really avoid setting the value in class code by accident. It works best if you never use this value anywhere else in classcode.
Another option is the "readonly" variable attribute. It enforces that the value must be set once (in the Constructor), but can also only be set once. You would still have to hand in the instance to the constructor or use static.
Another option is to add a static variable to store the data. But that is a pattern that is absolutely not adviseable. If you never need a second set of these instances with a different shared value, you have lost. And this will happen, as sure as the Garbage Collection. We got literal decades worth of experience of static values backfiring. So you really should stay with instance variables.
Another way is to add a Factory method. Often they are used if the instances need setup you can not leave to the average programmer using your code. You could even slightly breakt the pattern by having both a public constructor and a instance Factory Method. If you use the factory method, the shared thing is copied over from them Instance it is called on. If you use the Public constructor, a new shared thing is created.
The way to reuse a resource among multiple instances of the function is to declare it as static. For example, let's say I want to reuse an HttpClient:
public static class PeriodicHealthCheckFunction
{
private static HttpClient _httpClient = new HttpClient();
[FunctionName("PeriodicHealthCheckFunction")]
public static async Task Run(
[TimerTrigger("0 */5 * * * *")]TimerInfo healthCheckTimer,
ILogger log)
{
string status = await _httpClient.GetStringAsync("https://localhost:5001/healthcheck");
log.LogInformation($"Health check performed at: {DateTime.UtcNow} | Status: {status}");
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I've implemented this model to avoid locks where I'm trying to fully replace the contents of a list, while reading from it.
Reference assignment is an atomic operation, but I don't really understand what happens if a read/iteration on the list is in progress while the reference is changed. Is this implementation correct?
public class Cache
{
IList<CacheEntry> cache = new List<CacheEntry>();
// this method gets called frequently
public CacheEntry GetForCompany(string companyId)
{
return this.cache.Where(c => c.id == companyId).FirstOrDefault();
}
// this method gets called every 5 minutes
public void OnUpdate(IEnumerable<CacheEntry> updatedCache)
{
this.cache = updatedCache.ToList();
}
}
Are the any issues or race conditions with the code above?
Its thread safe in the sense than nothing will actually break or fail but, Linq being lazy, if the Where clause is materialized a considerable time later than the call to GetForCompany you can get very stale results because the query will return the results of the dated cache, even if the cache has been updated in the mean time.
Are the any issues or race conditions with the code above?
It might result in something similar to phantom read. So the answer will be PhantomRead.BelongsTo(RaceCondition)
I will explain it in low level pointer way even though you can't access it in c#
after the call OnUpdate this.cache pointer will be pointing to a memory address lets say 0x4
Then you called GetForCompany. The .Where call will store the current address of this.cache which is 0x4
Then you called OnUpdate again and this.cache became 0x100
When the Where clause enumerate thru the list it will still be looking at the list located at 0x4. Which means there are actually two sets of list in the memory at that time. The one stored in linq is 0x4 and the new one is 0x100.
Enumerating thru 0x4 will not give you any trouble since that list is not modified at all
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I've been introducing some new C# language features to my team - safe navigation is one of those.
Are there any significant performance reasons to avoid usage of safe navigation for every single object/property call?
e.g.:
myObject?.Field?.FieldValue
vs.
myObject.Field.FieldValue
I know this makes it so every field is null checked - but outside of a tight loop, don't the bugs this catches make it worth it? Or does this encourage lazy coding?
EDIT:
I found an entire article on this topic, hopefully it is helpful for others!
don't the bugs this catches make it worth it?
Quite on the contrary: applying safe navigation everywhere would hide bugs, rather than catching them.
Navigating a null reference by mistake is a bug in the implementation which could mean one of two things:
A field from which you navigate was not supposed to be null
You forgot to null-check a field that is legitimately null
Applying safe navigation is a good choice for case #2, because it lets you perform null check with less code. However, it is a poor choice for case #1, because it lets the object or a variable remain in a state that is incorrect from the standpoint of your program's logic.
That is why programmers should use their discretion when applying safe navigation, deciding each case individually.
Don't safely Navigate when
1) Null is actually an invalid logic for what you're doing
public string ProcessHash(User user)
{
var hash = user?.Password?.Hash
...
}
It's called Safe Navigation not Easy Null Check for a reason. Imagine you're destined to read the code above.
Does ProcessHash expect the user parameter as a null argument? If so, is the Password property of it also supposed to become null? How would you know if the previous coder has used "?." instead of "." just because he's a fan of Elvis? you'd have to analyse the whole code to find out.
2) Null is having another meaning than an unavailability in your code
What does a blind man see? Darkness? Or simply nothing?
What is an empty grocery basket?
// This is a good
Basket<Grocery> basket = new Basket<Grocery>();
var count = basket.Count(); // returns 0
// This smells bad!
Basket<Grocery> basket = null
var count = basket?.Count ?? 0;
3) You're using ?. and extension methods as a pipeline operator!
Don't use ?. to chain Properties and Methods together just because it reduces the lines you write and makes your code cool. there's lots of more well thought high level abstractions behind pipelines in fancy functional codes you see in other languages.
var resp = this.Bind<IceCreamDTO>()?.Validate()?.ToEntity()?.Insert()?.ToResponse();
There's 2 thing wrong with kind of code above.
Imagine if there was an error while validating the bound object. can you return what was wrong with it to the requester? well you can... but it's bad.
// That's not how this works. that's not how any of this works.
try
{
var resp = this.Bind<IceCreamDTO>()?.Validate()?.ToEntity()?.Insert()?.ToResponse();
...
} catch (ValidationException exp)
{
return exp.Errors.ToResponce();
}
well not clearly in the example above(realize it's all method calls not property calls), this also might break encapsulation principles if you're Navigating methods and properties together.
// Privacy violation
bool passwordValidation = user?.Password?.Hash?.Validate(hash);
// Property Security
bool passwordValidation = PasswordHash.Validate(user, hash);
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have an application that have several methods which checks for various errors on a computer. Right now i am calling the methods on load event of the form, but i kinda want to display what the program is doing by updating a label text for everything it does, like a progressbar. It should go from method to method in order.
And later i also want to check if everything has runned successfully. Should i look into Threading Tasks for this? Like starting a task for each method, stopping the task if it fails?
I would suggest to create the following classes:
WorkstationCheckBase - should be the base class for all checks.
WorkstationCheckRunner - gets a list of all checks and summarize
the result of each WorkstationCheckBase.
With that, you will encapsulate the checking from your UI and separete these concepts.
Now for you second question to show up on the UI some information (my assumation is that you use WinForm). For that you need a background task and update the UI frequently. You could use the Backgroundworker class for that.
Short answer: No, don't use threading-
Long answer: It depends!
When you get yourself into threading you start to face loads of other concurrency related problems, if all you want is to show a label of what is happening I would not suggest to use threads.
Since I have no code to look at I can only give you suggestions for how to solve your problem (without threading). The simplest way would be:
public void CheckErrors()
{
string errorText = string.Empty;
if (ErrorOneHasOccured(out errorText))
{
ErrorLabel += errorText;
}
errorText = string.Empty;
if (ErrorTwoHasOccured(out errorText))
{
ErrorLabel += errorText;
}
}
private bool ErrorOneHasOccured(out string errorText)
{
bool errorHasOccured = false;
errorText = string.Empty;
// DO error checking somehting
if (errorHasOccured)
{
errorText = "An error description";
return true;
}
return false;
}
Where :
ErrorLabel is the string property for the error text you want to display.
ErrorOneHasOccured is an example method for error checking, using the "Try" pattern.
I think this is the simplest way you can do it, but you can obviously engineer it further depending on what and why you need it.