C# Task.Result is Null [duplicate] - c#

This question already has answers here:
'await' works, but calling task.Result hangs/deadlocks
(6 answers)
Closed 4 years ago.
I have following method which will eventually return some Task<IList<DataModel>> but for now just returns null. I want to load result of this list to ObservableCollection in my ViewModel which is then displayed in a ListView.
But for now, I just want to return null and check that that is handled properly, so my ListView should show nothing in it as a result. I simmulate that by this code:
public async Task<IList<DatatModel>> GetData(string id)
{
return await Task.FromResult<IList<DataModel>>(null);
}
I call the code above and will loop through result of my Task and load it all in my ObservableCollection like so:
public void Initialize()
{
foreach (var data in GetData(Id).Result)
{
MyObservableCollection.Add(data);
}
}
However, my app just freezes. I think that above call to GetData(id).Result is problem because Result is null. How do I loop through this data and load it into my ObservableCollection if some data exist, or simply dont load anything if there is no data returned?

Instead of returning null, return an empty List<DataModel>. That way, your Result property will always be populated. So, your GetData method would become:
public async Task<IList<DatatModel>> GetData(string id)
{
return await Task.FromResult<IList<DataModel>>(new List<DataModel>());
}

Related

Unable to remove an object from an IList<T> using delegate <Action> method| C# Console Application [duplicate]

This question already has answers here:
Collection was modified error when looping through list and removing items
(6 answers)
Closed 10 days ago.
Here is my list:
public IList<Food> Foods { get; } = new List<Food>();
The generic method which recives IList and an Action as it's argument:
public void Process<T>(IList<T> items, Action<IList<T>> disposal)
{
disposal(items);
}
The way I did inside Main method:
using Generics03.Models;
using Generics03.Systems;
Multislut ms=new Multislut(){};
ms.Foods.Add(new Food());
ms.Foods.Add(new Food());
ms.Foods.Add(new Food());
ms.Process<Food>(ms.Foods,(f)=>{
f[0].Name="Pizza";
f[0].Region="Italy";
//when adding the following method, the project doesn't run!
f.GrowKale();
//Composter.cs where the Growkale method is defined in
public static class Composter
{
public static void GrowKale(this IList<Food> foods)
{
foreach (var item in foods)
{
foods.Remove(item);
}
}
}
All I need to do is to remove ms.Foods objects that I've added in Program.cs/Main(), I'm able to assign value to their properties but not able to remove or even add object to the ms.Foods list, getting the following exception message:
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
Is there a way to do so?
You should create a copy of the List before you try remove items,
You can't remove items from the List you are Enumerating without throwing the exception you are seeing, This is to stop you from creating situations where you end up with new and old values and forces you to start again.
The easiest way to do this is with .ToList()
foreach (var item in foods.ToList())
{
foods.Remove(item);
}
to make it easier to read/understand you could also do this
var theComposter = foods.ToList();
foreach (var food in theComposter)
{
foods.Remove(food);
}
You should also consider using a lock whenever you try to get/set the foods so you don't see this error again if you use multiple threads.

Adding more detail to await Task<T> in C# .net

The Task object created in C# contains the details for the completion of the Action ascribed to the Task. So even if the Action fails the task is still IsCompleted, unless the Task throws an exception or is cancelled.
What I am trying to do is to create a Task-Like class (easy, done that bit) that can store more information about the job that was done.
So for example I want an API to get some accounts, the results may throw an exception, say SQLConnection Exception for example, fine, but also the results may be empty and I want to know why. Is the Database empty or has a filter restricted the view to nothing, for example?
So I could do:
var t = AccountResposistory.GetAccountsAsync(filter, token);
var results = await t;
if(t.Success)
{
return Results.Ok(results)
}
else
{
return Results.Problem(t.ErrorMessage);
}
I was heading down the path of using a custom Task-Like object something like:
public async ServiceTask<IEnumerable<Account>?> GetAccountsAsync(Filter filter, CancellationToken token)
{
// Get accounts with filtering
if(Accounts.Any())
{
return Accounts;
}
else if(filter != null)
{
return ServiceTask.FromError("Filter has restricted all Accounts");
}
else
{
return ServiceTask.FromError("Database doesn't contain any Accounts");
}
}
I can have ServiceTask.FromError return a default T but there's no way (I can see) to access the ServiceTask that's returned by the method to add in the details.
Alternatively, I figured I could have ServiceTask always return a generic Response class and then work with the properties inside ServiceTask to apply the results or messages, but I can't figure out how to do that, how to restrict ServiceTask that T is always a generic class of ServiceResponse
I don't like the idea of throwing exceptions when an exception hasn't happened. It's not a code exception when the database is empty, or the filter has removed all accounts.
Currently, my GetAccountsAsync is returning a Task<Response> and the Response has Success, ErrorMessage and Results properties. It becomes a bit cumbersome to work around this, to get the results of the awaited results. I'm hoping there's a simple way to code this.

Why code works with SaveChanges but not with SaveChangesAsync [duplicate]

This question already has answers here:
Entity Framework SaveChanges() vs. SaveChangesAsync() and Find() vs. FindAsync()
(3 answers)
Closed 5 years ago.
I'm using ASP.NET MVC Core 1.1 with VS2015. I would like to understand the following in a portion of my controller code: The last line of the following code gives the error: There is already an open DataReader associated with this Command which must be closed first.. But if I change SaveChangesAsync() to SaveChanges() code works fine.
Snapshot of Controller:
public IActionResult myActionMethod(...)
{
...
var oRecToUpdate = _context.Order.Where(c => c.OrdersId == 104).SingleOrDefault();
if (oRecToUpdate != null)
{
oRecToUpdate.Price = 98.09;
_context.SaveChangesAsync();
}
string sStateNumer = _context.StateNames
.Where(s => s.State == "myState").Select(t => t.StateNumber).SingleOrDefault();
....
}
Because you are calling an asynchronous method on the context, it's potentially still running by the time you get to the next query. You need to await the call to prevent this:
await _context.SaveChangesAsync();
Or call the non-asynchronous version:
_context.SaveChanges();

Why would a NullReferenceException get thrown because my method returns null? [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
As shown below I have a method in my class that returns null as expected when it does not successfully read a value. I assume that the object "test" would just be set to NULL but for some reason an error is getting thrown.
I don't understand why this would throw an error...
private string myNullFunction() { return null; }
private void myFunction()
{
object test = myNullFunction();
}
when this does not...
private void myFunction()
{
object test = null;
}
Your sample code does not actually throw an exception. The real issue is shown in the code snippet above the exception dialog: m_xml.Read is returning null, but you are trying to access the Value property.
Read function is returning null. That's why null reference exception is there.

How to check in MongoDB C# Driver if updated successfully?

I am using the following code to update data using the MongoDB C# Driver:
public async Task<bool> UpdateFirstName(string id, string firstName)
{
await Collection.UpdateOneAsync(Builders<User>.Filter.Eq(
"_id", new ObjectId(id)),
Builders<User>.Update.Set("firstName", firstName)
.CurrentDate("lastUpdatedDate"));
}
This method returns "bool", because I want to know if the data has been updated successfully. This would be the pseudocode for checking if the data has been updated successfully:
if (data updated successfully)
{
return true;
}
else
{
return false;
}
Does anyone know how to write the code for checking if the data updated successfully? Thanks!
If the method was executed so the update was done, otherwise the method will throw an exception - In case of async it's important to not forget the await (since using async method without await can't ensure your application stay around long enough to retreive the exception)
UpdateOneAsync has a return value of UpdateResult?, which gives you access to the ModifiedCount. As you you UpdateOne a single greater 0 check is enough.
var response = await Collection.UpdateOneAsync(Builders<User>.Filter.Eq(
"_id", new ObjectId(id)),
Builders<User>.Update.Set("firstName", firstName)
.CurrentDate("lastUpdatedDate"));
if response.ModifiedCount > 0 {
// success
}
// failed
This will throw an Exception if the Update is not acknowledged.

Categories

Resources