I've got some troubles with StreamReader.ReadToEndAsync();
//some get response code ...
using (var response = getResponseTask.Result)
{
using (var responseStream = response.GetResponseStream())
{
using (var responseStreamReader = new StreamReader(responseStream))
{
var readToEndTask = responseStreamReader.ReadToEndAsync();
var responseResult = await readToEndTask;
//and some json parse code here
}
}
}
So, when I press the Home button on the device (whatever phone or emulator) while ReadToEndAsync task is in process, result string is not full length on app reactivation... i.e. it's ending just cut out without any exceptions or warning.
As result, I can't parse my json-data to object.
How can I fix it or avoid this situation ?
Thanks everybody in advance!
For this, you need to run your code as a background task. Background tasks will run even your app is deactivated. You can refer : https://learn.microsoft.com/en-us/windows/uwp/launch-resume/support-your-app-with-background-tasks to learn background tasks.
There are two types of background tasks, in process & out process.
Related
I am trying to achieve a simple streaming (non buffered output) using really basic ASP.NET Core 6 app.
The following simple code should output the hello world text to the client and then close the connection (even by adding the document IHttpResponseBodyFeature option) :
app.MapGet("/a", async (ctx) =>
{
var gg = ctx.Features.Get<Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature>()!;
gg.DisableBuffering();
await ctx.Response.Body.WriteAsync(Encoding.UTF8.GetBytes("Hello, World!"));
await ctx.Response.Body.FlushAsync();
await Task.Delay(2000);
});
This is of course a simple example of a behavior I am trying to achieve.
Simple curl request to the app can show that the hello world text is reaching to the client only after the 2 seconds wait.
On the .NET Framework the following code works as expected:
Response.Clear();
Response.Buffer = false;
Response.BufferOutput = false;
Response.Output.WriteLine("Hello World!");
Response.Output.Flush();
System.Threading.Tasks.Task.Delay(2000).Wait();
Response.End();
Simple curl request shows the "hello world" text shown immediately and after 2 seconds the connection get closed.
Thanks in advance.
After few more tries and searches i came upon the following issue on github :
https://github.com/dotnet/aspnetcore/issues/26565
Using the code there i managed to came up with a simple way for working non buffered output (also works on app.MapGet as shown on the question):
HttpContext.Response.StatusCode = 200;
await using var bodyStream = HttpContext.Response.BodyWriter.AsStream();
await HttpContext.Response.StartAsync();
for (var i = 0; i < 3; i++)
{
await bodyStream.WriteAsync(Encoding.UTF8.GetBytes(Convert.ToBase64String(new byte[128 * 1])));
await bodyStream.FlushAsync();
await Task.Delay(2000);
}
await HttpContext.Response.CompleteAsync();
return Ok();
My app had some middle-ware which made debugging worse, disabling it made everything much simpler on my app/scenario.
Thanks for the comments , i hope this helps.
The code below, runs for about fifteen seconds on the "dataFs = await _Http.GetStreamAsync(BODIST_DATA_HTTPNAME)" line before failing with a "System.Net.Http.HttpRequestException: TypeError: Failed to fetch".
public async Task<Double> EffectivePipCount(HttpClient _Http, Int64 _PositionId)
{
Double retVal = Double.NaN;
using (Stream locnFs = await _Http.GetStreamAsync(BODIST_LOCATION_FILENAME)
, dataFs = await _Http.GetStreamAsync(BODIST_DATA_FILENAME))
{
retVal = EffectivePipCount(_PositionId, locnFs, dataFs);
}
return retVal;
}
The file in question is about four gigabytes in size.
This is in Blazor WebAssembly app, so I want an Http equivalent to a FileStream, where I can seek and then read the hundreds of bytes I want. Small files in the same directory work fine.
If the problem is a timeout because of the file size, what should I be using instead of HttpClient.GetStreamAsync()?
My best guess is that GetStreamAsync() pulls down the whole file. Using http.GetFromJsonAsync solves the problem.
In Xamarin.Forms prerelease they have released a media picker: https://learn.microsoft.com/en-us/xamarin/essentials/media-picker?tabs=android
This is obviously a great addition and the fact that you don't have to use any 3rd party-library is great!
I'm creating an event management app - in the app the user can select an image for the event and be able to see it.
Here is my code:
public async void OnSelectPhotoCommand()
{
var photo = await MediaPicker.PickPhotoAsync();
await LoadPhotoAsync(photo);
}
async Task LoadPhotoAsync(FileResult photo)
{
var newFile = Path.Combine(FileSystem.CacheDirectory, photo.FileName);
using (var stream = await photo.OpenReadAsync())
using (var newStream = File.OpenWrite(newFile)) { await stream.CopyToAsync(newStream); }
ImagePath = newFile;
}
The problem is the image is not showing or appearing whatsoever - I've tried to modify my code and debug it but I am unable to locate the source of the problem.
I want the user to be actually able to see the image - but I am unsure on how to do that using the MediaPicker without putting it in the Android Resources folder?
Thank you,
tommy
From the xamarin essentials documentation be sure to be running it from the UI Thread.
InvokeOnMainThread ( () => {
OnSelectPhotoCommand();
});
I'm implementing a Windows Phone 8.1 App with a QR Code reader. I use ZXing.NET to analyze the taken image and try to parse the QR. To increase it's efficiency I also set autofocus to the camera. It works pretty well at the first start, but not with the second try (f.e. after suspend - resume or restart capturing). As I tested, the FocusAsync method doesn't return sometimes and blocks everything.
What happens here? What could be the problem?
Here is my current code.
Focus
var focusSettings = new Windows.Media.Devices.FocusSettings();
focusSettings.AutoFocusRange = Windows.Media.Devices.AutoFocusRange.Normal;
focusSettings.Mode = Windows.Media.Devices.FocusMode.Auto;
CaptureManager.VideoDeviceController.FocusControl.Configure(focusSettings);
MainProcess
... Initialization ...
ImageEncodingProperties imaggeProperties = ImageEncodingProperties.CreateJpeg();
imaggeProperties.Width = ViewModel.ImageWidth;
imaggeProperties.Height = ViewModel.ImageHeight;
InMemoryRandomAccessStream memoryStream = new InMemoryRandomAccessStream();
LoggingAdapter.Instance.WriteDebugLog("Scanning is in progress. " + Environment.CurrentManagedThreadId);
await CaptureManager.VideoDeviceController.FocusControl.FocusAsync();
await CaptureManager.CapturePhotoToStreamAsync(imaggeProperties, memoryStream);
LoggingAdapter.Instance.WriteDebugLog("Photo captured.");
var bcReader = new BarcodeReader();
... Processing the barcode ...
Cleaning
if (CaptureManager != null)
{
if (InProgress)
{
InProgress = false;
await CaptureManager.StopPreviewAsync();
}
CaptureManager.Dispose();
Capture.Source = null;
}
Thanks for advance!
I succeeded to implement a working solution. I set the the WaitForFocus to false in the FocusSettings and it seems to be working fine, also with suspending or cancelling.
I'm starting a 3rd party command line application from my C# program using this part of code.
// define Process Start Info and give filename of the 3rd Party app
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(FileName);
myProcessStartInfo.CreateNoWindow = true;
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardInput = true;
myProcessStartInfo.RedirectStandardOutput = true;
theProcess.StartInfo = myProcessStartInfo;
// instantiate observer class that contains a function
// (ProcessStandardOutput) that is run in separate thread
observer = new StreamObserver();
// create the thread
outputObserverThread = new Thread(observer.ProcessStandardOutput);
// start the 3rd party console application
theProcess.Start();
// set the input stream (to send commands to the console app)
commandStream = theProcess.StandardInput;
// connect the output stream with the observer class
observer.SetOutputStream(theProcess.StandardOutput);
// start the observer thread
outputObserverThread.Start();
// send any command to the console app
SendCommand("init");
This is actually nothing special and has been taken 70% from C# documentation example.
It works so far. I can send commands using the SendCommand() to the console application and I'm getting the response back.
But at one point the output stream gets stuck. Meaning I do not get any text back and even the end of the previous textblock is missing.
Sending commands that result usually in just one line of reply will not be passed to the stream.
A command that usually produces a hugh reply (e.g. "help") will "flush" the stream and I'm getting text through the stream (including the missing data)
This is the (stripped down) implementation of the StreamObserver which processes the output stream:
public class StreamObserver
{
// Volatile is used as hint to the compiler that this data
// member will be accessed by multiple threads.
private volatile bool _shouldStop;
private volatile StreamReader outputStream;
// This method will be called when the thread is started.
public void ProcessStandardOutput()
{
while (!_shouldStop)
{
string line = outputStream.ReadLine();
Console.WriteLine(line);
}
}
public void SetOutputStream(StreamReader stream)
{
outputStream = stream;
}
}
Nothing magic here either....
Any idea what could cause the stream to get stuck and recover when hugh data is present?
I have just counted the returned text. It looks like a block has to contain ~4k data before it is send to the output stream.
Does that ring any bell???
Btw, I'm running on Windows 7 64bit and Use Visual Studio 2013 prof.