BitmapImage SetSource Crashing/Freezing App - windows-runtime

I am trying to set the image from a stream. However when I set the source from the background thread and use a dispatcher it freezes the app completely. The stream is not null, I have verified that.
I am using the taglib api to get the stream of the album picture of an mp3 file. I've tried everything.
async void Background(object sender, MediaPlayerDataReceivedEventArgs e)
{
IRandomAccessStream AlbumArtStream = await Media.GetAlbumArt(MediaFile.Name, await MediaFile.OpenStreamForReadAsync());
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
ViewModel.NewAlbumArt = new BitmapImage();
NewAlbumArt.SetSource(AlbumArtStream);
}
}

Like in comment - to prevent freezing your app, call SetSoruceAsync:
async void Background(object sender, MediaPlayerDataReceivedEventArgs e)
{
IRandomAccessStream AlbumArtStream = await Media.GetAlbumArt(MediaFile.Name, await MediaFile.OpenStreamForReadAsync());
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
ViewModel.NewAlbumArt = new BitmapImage();
await NewAlbumArt.SetSourceAsync(AlbumArtStream);
}
}
You may read more at MSDN:
Setting an image source by calling the asynchronous SetSourceAsync method rather than the similar SetSource method avoids blocking the UI thread. ...

Related

How to call a get REST API from a tvOS Application using Xamarin?

I am trying to call a get REST API from my tvOS application. Following is my code when tap the Button:
async void ButtonClicked(UIButton sender)
{
try
{
HttpClient client = new HttpClient();
var response = await client.GetAsync("rest api url");
if (response.IsSuccessStatusCode)
{
var Response = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrWhiteSpace(Response.ToString()))
{
var category = JsonConvert.DeserializeObject<Videos>(Response.ToString());
Debug.WriteLine("count:>>" + category.webContentCategoryList.Count);
}
}
}
catch(Exception e)
{
Debug.WriteLine("Exception:>>"+e);
}
I have installed the system.net.http and newtonsoft.json nuget packages. But when I run the project the application showing Main.cs file like below screenshot:
Am I missing something in this?
UPDATE
I have added breakpoint for the first line inside ButtonClicked function. When I taps the Button, the application showing Main.cs file like above screenshot. It is not hitting the first line of ButtonClicked function.
So the issue is something else, I am not an expert in tvOS applications so I can't figure out. I have uploaded a sample project here.
I have fixed this issue by separating the service call on a new function like below, new function is the async method:
partial void ButtonClicked(UIButton sender)
{
LoadData();
}
async void LoadData()
{
HttpClient client = new HttpClient();
var response = await client.GetAsync("service url");
if (response.IsSuccessStatusCode)
{
var Response = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrWhiteSpace(Response.ToString()))
{
var category = JsonConvert.DeserializeObject<Videos>(Response.ToString());
Debug.WriteLine("count:>>" + category.Count);
}
}
}
My XF Thread is here for more details.

How to get Angularjs scope variable after reloadWithDebugInfo?

I have an angularjs web page and want to get the specified element's scope. But after executing the reloadWithDebugInfo function, the result is null;
private Page _page;
private Browser _browser;
private async void button1_ClickAsync(object sender, EventArgs e)
{
try
{
await initAsync();
await test2Async();
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.Message);
}
}
private async Task initAsync()
{
_browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = false,
ExecutablePath = #"c:\Program Files (x86)\Google\Chrome\Application\chrome.exe",
Timeout = 60000
});
}
private async Task test2Async()
{
try
{
_page = await _browser.NewPageAsync();
await _page.GoToAsync("https://SOME Angular JS WebPage");
await _page.EvaluateFunctionAsync(#"() => angular.reloadWithDebugInfo()");
var scopeContent = await _page.EvaluateFunctionAsync("() => angular.element(document.getElementsByClassName('left-column-v3')).scope() ");
// scopeContent is null. why? (the above javascript code runs successfully in the chrome dev console.)
}
catch (Exception ex)
{
MessageBox.Show("Error : " + ex.Message);
}
}
These statements works well in chrome dev tools.
I expect the json content of the scope, but that is null;
Update:
sorry, I forgot something after Scope().
I want a variable in the scope, not scope itself:
var scopeContent = await _page.EvaluateFunctionAsync("() => angular.element(document.getElementsByClassName('left-column-v3')).scope().SomeVariable ");
The problem is that the result of the scope function is not serializable.
You would need to build a serializable object inside the EvaluateFunctionAsync and return that.

How to Store Object to windows phone 8.1

In wp8.0 we can store object to IsolatedStorageSettings. wp8.1 object was not storing. Is there any way to store object to wp8.1.
WRITE OBJECT CODE
NewsList = new ObservableCollection<New>(e.News);
var FileName = "News.xml";
DataContractSerializer serializer = new DataContractSerializer(typeof(ObservableCollection<New>));
var localFolder = ApplicationData.Current.LocalFolder;
var file = await localFolder.CreateFileAsync(FileName,CreationCollisionOption.ReplaceExisting);
IRandomAccessStream sessionRandomAccess = await file.OpenAsync(FileAccessMode.ReadWrite);
IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
serializer.WriteObject(sessionOutputStream.AsStreamForWrite(), NewsList);
READ OBJECT CODE
var FileNameNews = "News.xml";
DataContractSerializer serializer = new DataContractSerializer(typeof(ObservableCollection<New>));
var localFolder = ApplicationData.Current.LocalFolder;
var newsFile = await localFolder.GetFileAsync(FileNameNews);
IInputStream sessionInputStream = await newsFile.OpenReadAsync();
newsVM = new NewsViewModel();
NewsVM.NewsList = (ObservableCollection<New>)serializer.ReadObject(sessionInputStream.AsStreamForRead());
im getting error on this link
IInputStream sessionInputStream = await newsFile.OpenReadAsync();
What mistake is there this code??
Thanks
This is how I do it. No using statements. I try to avoid the Stream syntax as much as possible.
Your error is very likely either because of concurrency (accessing the same file at the same time will throw an exception), or because the stream was not closed properly. I think it is the latter.
You do not dispose of your Stream objects properly (learn the using () {} syntax), which means that the stream remains OPEN after you're done writing. That means you hit the concurrency issue the second time you write, because you're trying to access a stream that's already open.
public async Task CreateOrUpdateData(string key, object o)
{
try
{
if (o != null)
{
var sessionFile = await _localFolder.CreateFileAsync(key, CreationCollisionOption.ReplaceExisting);
var outputString = JToken.FromObject(o).ToString();
await FileIO.WriteTextAsync(sessionFile, outputString);
}
}
catch (Exception e)
{
Debug.WriteLine("Encountered exception: {0}", e);
}
}
public async Task<T> GetDataOrDefault<T>(string key, T defaultValue)
{
try
{
T results = defaultValue;
var sessionFile = await _localFolder.CreateFileAsync(key, CreationCollisionOption.OpenIfExists);
var data = await FileIO.ReadTextAsync(sessionFile);
if (!String.IsNullOrWhiteSpace(data))
{
results = JToken.Parse(data).ToObject<T>();
}
return results;
}
catch (Exception e)
{
Debug.WriteLine("Encountered exception: {0}", e);
}
return defaultValue;
}

Windows phone httpclient not working

I have the following code. The async call never returns anything. Even for google.com.
try
{
using (
var client = new HttpClient()) {
var response = client.GetAsync("http://www.google.com");
Debug.WriteLine("Coming here1"+response.Result.IsSuccessStatusCode);
if (response.Result.IsSuccessStatusCode)
{
// by calling .Result you are performing a synchronous call
Debug.WriteLine("Coming here1");
var responseContent = response.Result.Content;
// by calling .Result you are synchronously reading the result
string responseString = responseContent.ReadAsStringAsync().Result;
//Console.WriteLine(responseString);
}
else { Debug.WriteLine("else"); }
}
}
catch(Exception e)
{
Debug.WriteLine(e.ToString());
}
}
Try This
try{
WebClient wc = new WebClient();
wc.DownloadStringCompleted+= (sender,args) => {
Debug.WriteLine(args.results);
};
wc.DownloadStringAsync(new Uri(#"http://www.Google.com",UriKind.RelativeOrAbsolute));
}
catch(Exception e){ Debug.WriteLine(e.Message); }
You don't appear to be awaiting your Async call.
Try changing var response = client.GetAsync("http://www.google.com"); to var response = await client.GetAsync("http://www.google.com");
Remember to mark your method as async.
you're also blocking on your async call ReadAsStringAsync().Result. As with client.GetAsync, make sure to await the call instead of blocking with Result. This blog post speaks a bit on the topic.
Read up a bit on async/await. You'll love it once you get the hang of it.

Message Dialog in Windows Store WITHOUT Async?

So, I'm porting an app over to Windows Store. At the start of the app, I have some code, that asks a question. I DO NOT WANT THE REST OF MY CODE TO FIRE UNTIL I GET A RESPONSE.
I have this:
string message = "Yadda Yadda Yadda";
MessageDialog msgBox = new MessageDialog(message, "Debug Trial");
msgBox.Commands.Add(new UICommand("OK",
(command) => { curSettings.IsTrial = true; }));
msgBox.Commands.Add(new UICommand("Cancel",
(command) => { curSettings.IsTrial = false; }));
await msgBox.ShowAsync();
//... more code that needs the IsTrial value set BEFORE it can run...
When I run the app, the code after the msgBox.ShowAsync() runs, without the correct value being set. It's only after the method finishes that the user sees the Dialog box.
I would like this to work more like a prompt, where the program WAITS for the user to click BEFORE continuing the method. How do I do that?
MessageDialog does not have a non-asynchronous method for "Show." If you want to wait for the response from the dialog before proceeding, you can simply use the await keyword.
Here also is a quickstart guide for asynchronous programming in Windows Store Apps.
I see that your code sample already uses "await". You must also mark the calling function as "async" in order for it to work properly.
Example:
private async void Button1_Click(object sender, RoutedEventArgs e)
{
MessageDialog md = new MessageDialog("This is a MessageDialog", "Title");
bool? result = null;
md.Commands.Add(
new UICommand("OK", new UICommandInvokedHandler((cmd) => result = true)));
md.Commands.Add(
new UICommand("Cancel", new UICommandInvokedHandler((cmd) => result = false)));
await md.ShowAsync();
if (result == true)
{
// do something
}
}