Async Deserialization call not working in C# - c#

I am using Newtonsoft.Json for reading a json file. I am trying to make a aysnc call to the json file to read its data but unfortunately it's not returning anything. I tried without async and it works perfectly, following is my code:
public static async Task<T> LoadAsync<T>(string filePath)
{
// filePath: any json file present locally on the disk
string basePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Replace("file:\\", "");
string fullPath = Path.Combine(basePath, filePath);
using (var stream = File.OpenRead(fullPath))
{
var reader = new StreamReader(stream, Encoding.GetEncoding("iso-8859-1"));
var task = Task.Factory.StartNew(() => JsonConvert.DeserializeObject<T>(reader.ReadToEnd()));
var value = await task;
return value;
}
}
I tried to debug but debugger is not coming on "return value" in the above method and I am calling above method by following function:
private void GetDataFromJson()
{
var value = JsonUtilities.LoadAsync<TaxOffice>(Constant.TAXJSONINPUTFILE);
}
What can be the problem ? File is present locally on my computer.

I am trying to make a aysnc call to the json file to read its data
Do you really want to make the code asynchronously? Does the JsonUtilities class offer a synchronous version of the LoadAsync() method?
Your method is synchronous:
private void GetDataFromJson()
{
var value = JsonUtilities.LoadAsync<TaxOffice>(Constant.TAXJSONINPUTFILE);
}
It does exactly one thing: it calls LoadAsync(). It does store the return value of that method in value, but you never use value. So it's ignored. The return value of LoadAsync() is not the TaxOffice object. It's a Task that represents the work LoadAsync() is doing. Until that task is done, there's no way to get a value. But GetDataFromJson() doesn't wait for the task to be done. So if the caller expects it to be done by the time the method returns, it's going to be sorely disappointed.
How best to fix your code is unclear, as you haven't provided a good, minimal, complete code example showing what you need help with. But there are two obvious strategies you can follow:
Make the method asynchronous:
private async Task GetDataFromJson()
{
var value = await JsonUtilities.LoadAsync<TaxOffice>(Constant.TAXJSONINPUTFILE);
// presumably you do something with "value" here?
}
This is the best approach. But it will require that the caller be able to correctly deal with an asynchronous call. It will likely need to be turned into an async method as well. And its caller. And so on, until you get to the top of your call stack (e.g. an event handler method).
It's a bit of a pain to switch to async throughout your call stack, but the code will work much better if you do. Your thread (probably a UI thread) won't get stuck waiting on the operation, and you'll be all set to correctly deal with other asynchronous operations as well.
Ignore the asynchronous nature of the LoadAsync() method:
private void GetDataFromJson()
{
var value = JsonUtilities.LoadAsync<TaxOffice>(Constant.TAXJSONINPUTFILE).Result;
// presumably you do something with "value" here?
}
This is the Not Very Good™ approach. It works. But it holds up your current thread until the asynchronous operation is done, negating the entire benefit of having an asynchronous operation in the first place.

Related

Tips for using async/await

I have been reading up on asynchronous programming in C# for the last few days. The reason for this is that the filepicker in UWP (necessary because I am programming for the Hololens 2 in Unity) is asynchronous. Despite many sources, i.e. 1, 2, 3, I have some understanding problems regarding the correct use and maybe experienced users here have a few tips for me.
An example of what I am trying to do:
Start of the programm:
public class SceneUIHandler : MonoBehaviour
{
openFile()
{
pickFile(); // calls await filepicker.PickSingleFileAsync();
loadData(path); // calls FileLoader.loadFile with path from filepicker for the reader
showData(); // should display the data
}
}
The Loader:
public class FileLoader:
{
async void loadFile(string path)
{
Task<StreamReader> streamReaderTask = getStreamReader(filePath);
StreamReader sr = await streamReaderTask;
// after that read file with the StreamReader...
...
}
async Task<StreamReader> getStreamReader(string path)
{
StorageFile file = await StorageFile.GetFileFromPathAsync(path);
var randomAccessStream = await file.OpenReadAsync();
Stream stream = randomAccessStream.AsStreamForRead();
StreamReader str = new StreamReader(stream);
return str;
}
}
So I get the path with the filepicker and later in the FileLoader class I call the file with the path and create a streamreader. So far everything works.
My problem is that if the creation of the reader takes longer the code stops because of await and jumps accordingly again in openFile() in SceneUIHandler after the method loadData(). But after that comes showData() and here I expect that the data is already loaded. From the tutorials I would now make openFile() async to write an await loadData() here.
If I do that I have to async one method after the other because I have to wait somewhere until the data is loaded otherwise i can't display, change, interact with the (not loaded) data. But by async + await I wait and continue in the previous method (which also relies on the data).
How or where do I have to stop, or do I have to separate the code differently when working with async so that the rest of the code flow is independent of the data?
I also get now a Cross thread invocation exception probably by creating and calling a slighty different getStreamReader(string path) method which just returns a BinaryReader instead of a StreamReader.
I also recommend reading my async best practices article. The first two best practices are still the most important.
From the tutorials I would now make openFile() async to write an await loadData() here.
The first best practice is "Avoid async void", because your code can't know when the method finishes. In other words, use async Task instead of async void, and await that method call.
If I do that I have to async one method after the other because I have to wait somewhere until the data is loaded otherwise i can't display, change, interact with the (not loaded) data. But by async + await I wait and continue in the previous method (which also relies on the data).
How or where do I have to stop, or do I have to separate the code differently when working with async so that the rest of the code flow is independent of the data?
The second best practice is "Use async all the way". It's normal to feel this is weird at first, but it is the correct procedure.
Eventually, you'll yield back to your framework. In the case of UWP/Unity, you'll have a UI at your highest level. And what you'll have to do is show some kind of "Loading..." screen (immediately and synchronously), and then update that when the asynchronous work completes. I have an article on async data binding that's written from an MVVM/WPF perspective, but the same ideas translate to any UI framework.
How or where do I have to stop, or do I have to separate the code differently when working with async so that the rest of the code flow is independent of the data?
Just from my point of view, the code that relies on the data needs to wait for the result, other code could run separately.
So something like this:
openFile()
{
// if it is a task
var tas = pickFile();
// TD
somework that not related to the file you get.
like setting UI size, change layout
textblock.text="this is the file";
textblock.background="";
//when all is done wait to get the file
string filepath = await task;
// code that needs the data
LoadAndShowData(filepath);
}

async library calls relying on each other and how to handle?

this is a follow on from a previous question I posted Calling an async method using a Task.Run seems wrong?
I thought the code written by the contractor was wrong but following on from the answers provided I'm now wondering if it's the libraries fault. This library exposes two methods that I need to use. One returns a "template" and one consumes part of this template (it does in my implementation anyway). But both are async methods returning Tasks.
To explain my library has methods:
public Task<TemplateInfo> TemplateInfo(TemplateInfoRequest request);
public Task<List<EmailResult>> SendMessageTemplate(SendMessageTemplateRequest request);
I need to call these thus:
public bool SendMessage()
{
var template = TemplateInfo(...);
var message = //use template to create message
var sendResponse = SendMessageTemplate(message);
return sendResponse.Count > 0;
}
So the second call relies on the first. This is where the async doesn't make sense to me. I can't and don't want to run these in parallel. I want to run them in sequence. I want my method to by synchonous.
An answer in my previous question also states:
Since you're blocking on an async method (which you shouldn't do)
there is a chance you'll deadlock.
So how do I access these async methods in such a way that they are processed in turn and return a synconhonous result but do not cause deadlocks?
Async doesn't (necessarily) means parallel.
You can call both async method sequentially without them running in parallel. Simply call the first and await the returned task and then do the same with the second.
var template = await TemplateInfo(...);
var message = //use template to create message
var sendResponse = await SendMessageTemplate(message);
This is still useful compared to synchronous code because while the asynchronous operation is "running" there's no thread needed and so your threads can go work on other parts of your application.
If you would call both and only then await the returned tasks you will (maybe) run in parallel:
var templateTask = TemplateInfo(...);
var sendResponseTask = SendMessageTemplate(message);
await templateTask;
await sendResponseTask;

Issues creating custom async method

I'm well aware there are built in async methods in C# now such as ToListAsync() etc. In the event that we would like to wrap async functionality around a library that does not provide it out of the box, it seems to be a little more difficult. However, perhaps I just don't understand async programming in C# enough.
This article on TAP makes it seem pretty simple
In Visual Studio 2012 and the .NET Framework 4.5, any method that is attributed with the async keyword (Async in Visual Basic) is considered an asynchronous method, and the C# and Visual Basic compilers perform the necessary transformations to implement the method asynchronously by using TAP. An asynchronous method should return either a System.Threading.Tasks.Task or a System.Threading.Tasks.Task object. In the case of the latter, the body of the function should return a TResult, and the compiler ensures that this result is made available through the resulting task object.
Using several examples I have come up with the following to try and make a heavy couchdb call async.
var allDocs = await _couchDbServices.Value.GetItemsForSearchAsync().Result.Rows;
public async Task<dynamic> GetItemsForSearchAsync()
{
return await RunQueryAsync("Items", "GetItemsForSearch", "include_docs=true");
}
public Task<LoveSeat.ViewResult<object>> RunQueryAsync(string designDoc, string view, string query)
{
return Task.Run(() => RunQuery(designDoc, view, query));
}
public LoveSeat.ViewResult<object> RunQuery(string designDoc, string view, string query)
{
//SetDefaultDesignDoc was causing issues with async query requests.
//Explicitly set the design doc in call to CouchDb.View -- DP
//CouchDb.SetDefaultDesignDoc(designDoc);
LoveSeat.ViewResult<object> result = CouchDb.View<object>(view + "?" + query, new ViewOptions(), designDoc); //empty view options required in new loveseat version --SB
return result;
}
The line var allDocs = await.... fails silently as soon as I add .Results.Rows to the call. This is somewhat confusing because if I am awaiting the call I shouldn't be getting back the Task, it should be a dynamic by this point. Breaking into code shows that it indeed is a dynamic when the line gets called without the .Results.Rows appended to it, yet intellisense does not seem to pick this up.
How can I get this async call to properly return a dynamic?
I am not completely sure but I would assume calling the await in this situation, it's thinking it needs to await the .Rows call, instead of the actual task you want to await (GetItemsForSearchAsync()). What does this code do for you:
var allDocsDynamic = await _couchDbServices.Value.GetItemsForSearchAsync();
var allDocs = allDocsDynamic.Result.Rows
Also, when returning a Task, it's redundant to use 'return await' since you will be calling await on the task that is returned.

Reading a text file and code jumps when using await

I am writing an app for windows 8.1 tablet and I am trying to read data from a text file I have saved (this text file is just over 1kb). The below code I have works on some occasions but mainly fails(debugging/stepping over the code will often see it succeed).
StorageFolder folder = ApplicationData.Current.LocalFolder;
string fileName = "collections.json";
public Dictionary<string, string> masterDataObject;
private async void CallLoad()
{
await this.Load();
}
public async Task<Dictionary<string, string>> Load()
{
//create a file
var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
string fileContents = string.Empty;
if (file != null)
{
//returns a JSON string
fileContents = await FileIO.ReadTextAsync(file);//WHY DOES IT JUMP AT THIS LINE?????
}
Dictionary<string, string> customerFromJSON = JsonCrt.DeserializeObject<Dictionary<string, string>>(fileContents) ?? new Dictiy<string, string>();
masterDataObject = customerFromJSON;
return masterDataObject;
}
After stepping through the code several times I can see at the line
fileContents = await.....
it drops out of the method and continues with the rest of the code that is not in my Load() method.
I have reviewed async and await and have really tried to understand it, but my understanding leaves me confused as to why this is happening.
I was under the belief that await meant that execution would stop until you get a response from the code you are calling (obviously not).
So how should I be using async to make it work properly, or is there a better alternative than this code?
I have looked and tried many options but so had no success, any advice would be gratefully received.
it drops out of the method and continues with the rest of the code that is not in my Load() method
That's exactly what it's ment to do, yield control to the calling site until the asynchronous operation completes.
I'm assuming your problem lays with the fact your CallLoad method is async void instead of async Task, thus cannot be awaited, and that's why you're seeing it continue without waiting for the internal async IO to complete.
I was under the belief that await meant that execution would stop until you get a response from the code you are calling
That is still entirely true, if you await the async operation all the way
So how should I be using async to make it work properly?
async void is ment only for top level event handlers. If CallLoad isn't used as one, it should be async Task and awaited: await CallLoad();
What await does behind the scenes:
it creates a callback which contains the code after await
it calls into the xyzAsync() function, registering the callback.
if the asynchronous operation finishes, the callback is called.
So if you step through the code with a debugger, it will execute some other code if it hits await returning to the code after the await as soon as the asynchronous operation has finished.

Is it possible to use same async method signature in C# 5.0 and be able to decide later how to execute such method

I want to use recent C# 5.0 async methods, however some specific way.
Consider following example code:
public abstract class SomeBaseProvider : ISomeProvider
{
public abstract Task<string> Process(SomeParameters parameters);
}
public class SomeConcreteProvider1 : SomeBaseProvider
{
// in this method I want to minimize any overhead to create / run Task
// NOTE: I remove here async from method signature, because basically I want to run
// method to run in sync!
public override Task<string> Process(SomeParameters parameters) {
string result = "string which I don't need any async code to get";
return Task.Run(() => result);
}
}
public class SomeConcreteProvider2 : SomeBaseProvider
{
// in this method, it's OK for me to use async / await
public async override Task<string> Process(SomeParameters parameters) {
var data = await new WebClient().DownloadDataTaskAsync(urlToRequest);
string result = // ... here we convert data byte[] to string some way
return result;
}
}
Now how I am going to use async methods (you can ignore fact that consumer actually ASP.NET MVC4 app in my case... it can be anything):
public class SomeAsyncController : AsyncController
{
public async Task<ActionResult> SomethingAsync(string providerId)
{
// we just get here one of providers I define above
var provider = SomeService.GetProvider(providerId);
// we try to execute here Process method in async.
// However we might want to actually do it in sync instead, if
// provider is actually SomeConcreteProvider1 object.
string result = await provider.Process(new SomeParameters(...));
return Content(result);
}
}
As you can see I have 2 implementations, each one will perform differently: one I want to run in async and do not block thread (SomeConcreteProvider2), while another one I want to be able to run in sync and do not create any Task object etc (which I fail to code in code above, i.e. I do create new Task here!).
There are questions already like How would I run an async Task<T> method synchronously?. However I don't want to run something in sync... I want to avoid any overhead if I know at code time (i.e. before runtime) that some methods implementations will NOT actually be async and will not need to use any threads / I/O completion ports etc. If you check code above, its easy to see that method in SomeConcreteProvider1 basically will construct some string (html), can do it very quickly at the same execution thread. However same method in SomeConcreteProvider2 will need to create Web Request, get Web Response and process it someway and I do want to make at least Web Request in Async to avoid blocking of whole thread during request time (may be quit long time actually).
So the question is: how to organize my code (different method signatures or different implementations, or?) to be able to decide how to execute method and avoid ANY possible overhead which caused for example by Task.Run(...) in SomeConcreteProvider1.Process method?
Update 1: obvious solutions (I think up some of them during question process), such as for example to add some static property to each of providers (say 'isAsyncImplementation') and then check that property to decide how to run method (with await or without await in controller action) have some overhead too :D I want something better if possible :D
In your first case, I would recommend returning:
Task.FromResult(result)
which returns a ready-completed task.
http://msdn.microsoft.com/en-us/library/hh194922%28v=vs.110%29.aspx
Your design looks fine.
For the SomeConcreteProvider1 case, you can use a TaskCompletionSource
This returns a Task without requiring concurrency.
Also, in the consumer code, await will not yield if the Task has already completed. This is called the "fast path" and effectively makes the method synchronous.

Categories