I am trying to cancel my tasks but it creating high cpu usage. My cpu goes to 100%
I tried different codes in internet all codes giving same output.
Start code
private async void BtnStart_Click(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
btnStart.Enabled = false;
btnStop.Enabled = true;
btnExport.Enabled = false;
btnOpen.Enabled = false;
btnClear.Enabled = false;
totalLinesCount = listBox_domains.Items.Count;
List<string> urls = new List<string>();
for (int i = 0; i < listBox_domains.Items.Count; i++)
{
urls.Add(listBox_domains.Items[i].ToString());
}
if (textBox_Proxies.Text != null)
{
for (int i = 0; i < textBox_Proxies.Lines.Length; i++)
{
proxyList.Add(textBox_Proxies.Lines[i]);
}
}
var maxThreads = (int)numericUpDown1.Value;
var q = new ConcurrentQueue<string>(urls);
tasks = new List<Task>();
for (int n = 0; n < maxThreads; n++)
{
tasks.Add(Task.Run(async () =>
{
while (q.TryDequeue(out string url))
{
await SendHttpRequestAsync(url, cts.Token);
Thread.Sleep(100);
}
}));
}
await Task.WhenAll(tasks).ContinueWith((FinalWork) =>
{
btnStart.Enabled = true;
btnExport.Enabled = true;
btnOpen.Enabled = true;
btnClear.Enabled = true;
MessageBox.Show(new Form { TopMost = true }, "Completed!", "Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}, TaskContinuationOptions.OnlyOnRanToCompletion);
}
Main task
private async Task SendHttpRequestAsync(string url, CancellationToken ct)
{
var httpClientHandler = new HttpClientHandler
{
Proxy = new WebProxy(GetProxy(), false),
UseProxy = true
};
try
{
using (HttpClient client = new HttpClient(httpClientHandler))
{
client.Timeout = TimeSpan.FromMilliseconds(1000 * (int)numericUpDown_timeout.Value); //adjust based on your network
//var byteArray = Encoding.ASCII.GetBytes("username:password1234");
//client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
try
{
using (HttpResponseMessage response = await client.GetAsync("URL" + url, ct))
{
using (HttpContent content = response.Content)
{
string result = await content.ReadAsStringAsync();
Regex match = new Regex(regex, RegexOptions.Singleline);
MatchCollection collection = Regex.Matches(result, regex);
try
{
await AddDataToDgv(url, collection[0].ToString(), collection[1].ToString(), collection[2].ToString());
}
catch (Exception ex)
{
await AddDataToDgv(url, "error", "error", "error");
}
}
}
}catch(Exception ex)
{
await SendHttpRequestAsync(url, ct);
retries++;
if (retries > (int)numericUpDown_Retries.Value)
{
retries = 1;
await AddDataToDgv(url, "timeout", "timeout", "timeout");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Stop code
private void BtnStop_Click(object sender, EventArgs e)
{
if (cts != null)
{
cts.Cancel();
btnStart.Enabled = true;
btnStop.Enabled = false;
btnExport.Enabled = true;
btnOpen.Enabled = true;
btnClear.Enabled = true;
MessageBox.Show(new Form { TopMost = true }, "Cancelled!", "Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
WHen I click on the stop the tasks are getting stopped but generating high cpu usage 100%.
Tried examples:
https://binary-studio.com/2015/10/23/task-cancellation-in-c-and-things-you-should-know-about-it/
https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/task-cancellation
When client.GetAsync is cancelled, it throws a TaskCanceledException. In this case, you don't want to retry.
Also, do not show MessageBoxes in your async SendHttpRequestAsync.
Related
I'm building a Taxi app and wanted to calculate the distance while the trip is going and update from the driver app side
I used Geolocator for live updates from https://github.com/jamesmontemagno/GeolocatorPlugin, I'm getting random locations and it's not stable on live updates so i changed getting the location after a minute
private async Task StartTrackingAsync(bool tracking)
{
try
{
PermissionStatus hasPermission = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (hasPermission != PermissionStatus.Denied)
{
// Permission Granted
// check for req
if (tracking)
{
// Check is listening...
if (CrossGeolocator.Current.IsListening)
{
// Start
CrossGeolocator.Current.PositionChanged += CrossGeolocator_Current_PositionChanged;
CrossGeolocator.Current.PositionError += CrossGeolocator_Current_PositionError;
}
else
{
CrossGeolocator.Current.PositionChanged += CrossGeolocator_Current_PositionChanged;
CrossGeolocator.Current.PositionError += CrossGeolocator_Current_PositionError;
object aType = "Automotive Navigation";
if (await CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(5), 50,
true, new ListenerSettings
{
ActivityType = ActivityType.AutomotiveNavigation,
AllowBackgroundUpdates = true,
DeferLocationUpdates = true,
DeferralDistanceMeters = 100,
DeferralTime = TimeSpan.FromSeconds(50),
ListenForSignificantChanges = true,
PauseLocationUpdatesAutomatically = false
}))
{
tracking = true;
}
}
}
else
{
CrossGeolocator.Current.PositionChanged -= CrossGeolocator_Current_PositionChanged;
CrossGeolocator.Current.PositionError -= CrossGeolocator_Current_PositionError;
await CrossGeolocator.Current.StopListeningAsync();
tracking = false;
}
}
else
{
// Permission Denied
await DisplayAlert("Location Error", "Error Getting Location", "OK");
}
}
catch (Exception ex)
{
// Error Accured
await DisplayAlert("Location Error", "Error Getting Location: " + ex.Message, "OK");
}
}
private void CrossGeolocator_Current_PositionError(object sender, PositionErrorEventArgs e)
{
}
private void CrossGeolocator_Current_PositionChanged(object sender, PositionEventArgs e)
{
Device.BeginInvokeOnMainThread(async () =>
{
Plugin.Geolocator.Abstractions.Position position = e.Position;
if (Cposition != e.Position)
{
Cposition = e.Position;
mainmap.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(position.Latitude, position.Longitude), Distance.FromMiles(1)).WithZoom(2));
loader.IsVisible = false;
mainmap.IsVisible = true;
local.Lat = position.Latitude;
local.Lng = position.Longitude;
}
});
}
private void DistanceUpdate(bool w = false)
{
Device.StartTimer(new TimeSpan(0, 0, 1), () =>
{
UpdateDistance();
return w;
});
}
private async void UpdateDistance()
{
// Get Trip Location
Models.Location SLocal = Trip.Location;
Xamarin.Essentials.Location startTrip = new Xamarin.Essentials.Location(SLocal.Lat, SLocal.Lng);
try
{
if (local != null)
{
Xamarin.Essentials.Location OnTrip = new Xamarin.Essentials.Location(local.Lat, local.Lng);
double distance = Xamarin.Essentials.Location.CalculateDistance(startTrip, OnTrip, DistanceUnits.Kilometers);
double t = tdistance + distance;
tdistance = Math.Round(t, 2);
if (Trip.Key != null)
{
_firebaseDatabase.UpdateTripDriverLocation(Trip.Key, local);
if (Trip.Status == "Started")
{
_firebaseDatabase.UpdateTripLocation(Trip.Key, local);
}
}
}
}
catch (Exception ex)
{
// Unable to get location
await DisplayAlert(ex.Source, "ERROR: " + ex.Message, "OK");
}
}
I'm not getting the current location but a random location and the distance produces more 5000km in 2 minutes before the driver starts moving
using System;
using System.ComponentModel;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Net;
namespace Seranking_Scraper
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
btnStop.Enabled = false;
}
CancellationTokenSource cts = null;
List<string> proxyList = new List<string>();
int _proxyIndex = 0;
int retries = 0;
int linesCount = 1;
int totalLinesCount;
List<Task> tasks = null;
string regex = "XXXXXX";
private static HttpClient client = null;
private async void BtnStart_Click(object sender, EventArgs e)
{
dataGridView1.Rows.Clear();
cts = new CancellationTokenSource();
btnStart.Enabled = false;
btnStop.Enabled = true;
btnExport.Enabled = false;
btnOpen.Enabled = false;
btnClear.Enabled = false;
totalLinesCount = listBox_domains.Items.Count;
List<string> urls = new List<string>();
for (int i = 0; i < listBox_domains.Items.Count; i++)
{
urls.Add(listBox_domains.Items[i].ToString());
}
if (textBox_Proxies.Text != null)
{
for (int i = 0; i < textBox_Proxies.Lines.Length; i++)
{
proxyList.Add(textBox_Proxies.Lines[i]);
}
}
var maxThreads = (int)numericUpDown1.Value;
var q = new ConcurrentQueue<string>(urls);
tasks = new List<Task>();
for (int n = 0; n < maxThreads; n++)
{
tasks.Add(Task.Run(async () =>
{
while (q.TryDequeue(out string url))
{
await SendHttpRequestAsync(url, cts.Token);
Thread.Sleep(1);
if (cts.IsCancellationRequested)
{
break;
}
foreach (Task eTask in tasks)
{
if (eTask.IsCompleted)
eTask.Dispose();
}
}
}, cts.Token));
}
await Task.WhenAll(tasks).ContinueWith((FinalWork) =>
{
Invoke(new Action(() =>
{
btnStart.Enabled = true;
btnExport.Enabled = true;
btnOpen.Enabled = true;
btnClear.Enabled = true;
timer1.Enabled = false;
timer1.Stop();
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Invoke((Action)(() => progressBar1.Value = 100));
if(!cts.IsCancellationRequested)
MessageBox.Show(new Form { TopMost = true }, "Completed!", "Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}));
}, TaskContinuationOptions.OnlyOnRanToCompletion);
//var options = new ParallelOptions()
//{
// MaxDegreeOfParallelism = (int)numericUpDown1.Value
//};
//Parallel.For(0, listBox_domains.Items.Count, async j =>
//{
// await SendHttpRequestAsync(listBox_domains.Items[j].ToString());
// Thread.Sleep(10);
//});
}
private string GetProxy()
{
if (proxyList.Count <=0) return null;
if (_proxyIndex >= proxyList.Count - 1) _proxyIndex = 0;
var proxy = proxyList[_proxyIndex];
_proxyIndex++;
return proxy;
}
private async Task ToCsV(DataGridView dGV, string filename)
{
await Task.Yield();
string stOutput = "";
// Export titles:
string sHeaders = "";
for (int j = 0; j < dGV.Columns.Count; j++)
sHeaders = sHeaders.ToString() + Convert.ToString(dGV.Columns[j].HeaderText) + "\t";
stOutput += sHeaders + "\r\n";
// Export data.
for (int i = 0; i < dGV.RowCount - 1; i++)
{
string stLine = "";
for (int j = 0; j < dGV.Rows[i].Cells.Count; j++)
stLine = stLine.ToString() + Convert.ToString(dGV.Rows[i].Cells[j].Value) + "\t";
stOutput += stLine + "\r\n";
//progressBar1.Style = ProgressBarStyle.Blocks;
//progressBar1.Value = (i / 100) * 100;
}
Encoding utf16 = Encoding.GetEncoding(1254);
byte[] output = utf16.GetBytes(stOutput);
FileStream fs = new FileStream(filename, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(output, 0, output.Length); //write the encoded file
bw.Flush();
bw.Close();
fs.Close();
}
private async Task SendHttpRequestAsync(string url, CancellationToken ct)
{
var httpClientHandler = new HttpClientHandler
{
Proxy = new WebProxy(GetProxy(), false),
UseProxy = true
};
//httpClientHandler.MaxConnectionsPerServer = 1;
httpClientHandler.AllowAutoRedirect = true;
httpClientHandler.MaxAutomaticRedirections = 3;
try
{
using (client = new HttpClient(httpClientHandler))
{
client.Timeout = TimeSpan.FromMilliseconds(1000 * (int)numericUpDown_timeout.Value); //adjust based on your network
client.DefaultRequestHeaders.ConnectionClose = true;
ServicePointManager.DefaultConnectionLimit = 100;
//var byteArray = Encoding.ASCII.GetBytes("username:password1234");
//client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
try
{
using (HttpResponseMessage response = await client.GetAsync("xxxx))
{
if (response.IsSuccessStatusCode)
{
using (HttpContent content = response.Content)
{
//response.Dispose();
string result = await content.ReadAsStringAsync();
Regex match = new Regex(regex, RegexOptions.Singleline);
MatchCollection collection = Regex.Matches(result, regex);
try
{
if (collection.Count > 0)
{
await AddDataToDgv(url, collection[0].ToString(), collection[1].ToString(), collection[2].ToString());
}
else if (result.Contains("No data for your search query"))
{
await AddDataToDgv(url, "nodata", "nodata", "nodata");
}
}
catch (Exception ex)
{
//MessageBox.Show(ex.ToString());
await AddDataToDgv(url, "errorCount", "errorCount", "errorCount");
}
}
}
else
{
await RetriesProxyFail(url, ct);
}
}
}catch(Exception ex)
{
await RetriesProxyFail(url, ct, ex);
client.Dispose();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public async Task RetriesProxyFail(string url, CancellationToken ct, Exception ex = null)
{
client.DefaultRequestHeaders.ConnectionClose = true;
if (!cts.IsCancellationRequested)
{
retries++;
if (retries > (int)numericUpDown_Retries.Value)
{
retries = 0;
Invoke(new Action(async () =>
{
lbl_RemainingLines.Text = "Remaining Urls: " + (totalLinesCount - (dataGridView1.Rows.Count)).ToString();
await AddDataToDgv(url, "timeout", "timeout", "timeout");
}));
}
else
{
await SendHttpRequestAsync(url, ct);
}
}
}
public async Task AddDataToDgv(string url, string tcost, string tTraffic, string tValue)
{
try
{
await Task.Yield();
Invoke(new Action(() =>
{
dataGridView1.Rows.Add(url, tcost, tTraffic, tValue);
lbl_RemainingLines.Text = "Remaining Urls: " + (totalLinesCount - (dataGridView1.Rows.Count)).ToString();
if (Application.RenderWithVisualStyles)
progressBar1.Style = ProgressBarStyle.Marquee;
else
{
progressBar1.Style = ProgressBarStyle.Continuous;
progressBar1.Maximum = 100;
progressBar1.Value = 0;
timer1.Enabled = true;
}
}));
}
catch (Exception ex)
{
Invoke(new Action(async () =>
{
lbl_RemainingLines.Text = "Remaining Urls: " + (totalLinesCount - (dataGridView1.Rows.Count)).ToString();
await AddDataToDgv(url, "error", "error", "error");
}));
}
}
private void BtnOpen_Click(object sender, EventArgs e)
{
linesCount = 1;
try
{
openFileDialog1.ShowDialog();
openFileDialog1.Title = "Please select text file that contains root domains.";
openFileDialog1.DefaultExt = "txt";
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.CheckFileExists = true;
openFileDialog1.CheckPathExists = true;
this.openFileDialog1.Multiselect = true;
myWorker_ReadTxtFile = new BackgroundWorker();
myWorker_ReadTxtFile.DoWork += new DoWorkEventHandler(MyWorker_ReadTxtFile_DoWork);
myWorker_ReadTxtFile.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MyWorker_ReadTxtFile_RunWorkerCompleted);
myWorker_ReadTxtFile.ProgressChanged += new ProgressChangedEventHandler(MyWorker_ReadTxtFile_ProgressChanged);
myWorker_ReadTxtFile.WorkerReportsProgress = true;
myWorker_ReadTxtFile.WorkerSupportsCancellation = true;
listBox_domains.Items.Clear();
foreach (String fileName_Domains in openFileDialog1.FileNames)
{
myWorker_ReadTxtFile.RunWorkerAsync(fileName_Domains);
}
}
catch (Exception ex)
{
}
}
private void OpenFileDialog1_FileOk(object sender, CancelEventArgs e)
{
}
private void MyWorker_ReadTxtFile_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
listBox_domains.Items.Add(e.UserState.ToString());
lbl_totallines.Text = "TLines: " + linesCount++.ToString();
}
private void MyWorker_ReadTxtFile_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
public void ReadLinesToListBox(string fileName_Domains)
{
using (StreamReader sr = File.OpenText(fileName_Domains))
{
string s = String.Empty;
while ((s = sr.ReadLine()) != null)
{
myWorker_ReadTxtFile.ReportProgress(0, s);
Thread.Sleep(1);
}
}
}
private void MyWorker_ReadTxtFile_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker sendingWorker = (BackgroundWorker)sender;//Capture the BackgroundWorker that fired the event
object fileName_Domains = (object)e.Argument;//Collect the array of objects the we received from the main thread
string s = fileName_Domains.ToString();//Get the string value
ReadLinesToListBox(s);
}
private void Label2_Click(object sender, EventArgs e)
{
}
private void BtnStop_Click(object sender, EventArgs e)
{
if (cts != null)
{
cts.Cancel();
cts.Dispose();
btnStart.Enabled = true;
btnStop.Enabled = false;
btnExport.Enabled = true;
btnOpen.Enabled = true;
btnClear.Enabled = true;
progressBar1.Style = ProgressBarStyle.Blocks;
progressBar1.Value = 100;
MessageBox.Show(new Form { TopMost = true }, "Cancelled!", "Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private async void BtnExport_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Excel Documents (*.xls)|*.xls";
sfd.FileName = "Site Metrics";
if (sfd.ShowDialog() == DialogResult.OK)
{
await ToCsV(dataGridView1, sfd.FileName); // Here dataGridview1 is your grid view name
}
MessageBox.Show(new Form { TopMost = true }, "Exported!", "Status", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
private void BtnClear_Click(object sender, EventArgs e)
{
listBox_domains.Items.Clear();
dataGridView1.Rows.Clear();
}
private void Form1_Load(object sender, EventArgs e)
{
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
}
private void BtnPasteProxies_Click(object sender, EventArgs e)
{
textBox_Proxies.Text = Clipboard.GetText();
}
private void Timer1_Tick(object sender, EventArgs e)
{
progressBar1.Value += 5;
if (progressBar1.Value > 100)
progressBar1.Value = 0;
}
}
}
The above code is working fine but the problem is it slowly increasing the memory usage. When I start it use some around 40 mb slowly its increasing I tried memory tests, the increase in memory is slow but its increasing slowly.
Any one help me whats wrong in my code?
I am testing with some 4k urls, when it reaches 2k urls my memory usage is 60 MB. Still increasing slowly.
A slow memory increase is totally normal. .NET uses Garbage Collection Memory Management approach. Now while the collection runs, every other thread has to stop. This can cause human noticeable stalls. And is one big reason GC and realtime programming do not mix that well.
To avoid those stalls, the GC is lazy with running. It is aiming for only running once - at application closure. Delays will not be that noticeable then. And it might even be able to save work, as the memory will be handed back to the OS afterwards and not be reused. Short of running finalizers, there might not be much work to be done.
There are only a few things that can force it to run earlier:
there is a danger of a OutOfMemory exception. The GC will have collected and defragmented everything it possibly could before you ever get that Exception.
you call GC.Collect(); It allows you to force a collection now. Note that this only adviseable for debugging and testing. Production code should not have this
you pick a GC strategy that differs from Desktop applciation default. There are ones that do the reachabiltiy checks in anotehr thread, to have that work not pause all threads. Ones that run regulary but avoid defragmentation. Even ones that run regulary with a upper bound on runtime (to limit the stalls).
I am testing the validity of a large list of proxy servers concurrently. During this testing, many exceptions are being raised and caught. Although I am doing the testing in a background thread, my UI becomes unresponsive unless I use a SemaphoreSlim object to control the concurrency.
I know this is a self imposed bottle neck, and when scaling with an even larger list of proxies to test, I was hoping there might be a better way to solve the problem.
private void ValidateProxiesButton_Click(object sender, EventArgs e)
{
new Thread(async () =>
{
Thread.CurrentThread.IsBackground = true;
await ValidateProxiesAsync(proxies, judges, tests, 10);
}).Start();
}
public async Task ValidateProxiesAsync(IEnumerable<Proxy> proxies, IEnumerable<ProxyJudge> judges, IEnumerable<ProxyTest> tests = null, int maxConcurrency = 20)
{
if (proxies.Count() == 0)
{
throw new ArgumentException("Proxy list empty.");
}
foreach (var proxy in proxies)
{
proxy.Status = ProxyStatus.Queued;
}
//Get external IP to check if proxy is anonymous.
var publicIp = await WebUtility.GetPublicIP();
foreach (var judge in judges)
{
judge.Invalidation = publicIp;
}
await ValidateTestsAsync(judges.ToList<IProxyTest>());
var validJudges = judges.ToList<IProxyTest>().GetValidTests();
if (validJudges.Count == 0)
{
throw new ArgumentException("No valid judges found.");
}
if (tests != null)
{
await ValidateTestsAsync(tests.ToList<IProxyTest>());
}
var semaphore = new SemaphoreSlim(maxConcurrency);
var tasks = new List<Task>();
foreach (var proxy in proxies)
{
tasks.Add(Task.Run(async () =>
{
await semaphore.WaitAsync();
proxy.Status = ProxyStatus.Testing;
var isValid = await proxy.TestValidityAsync((IProxyTest)validJudges.GetRandomItem());
proxy.Status = isValid ? ProxyStatus.Valid : ProxyStatus.Invalid;
semaphore.Release();
}));
}
await Task.WhenAll(tasks);
}
Inside proxy.TestValidityAsync method
public async Task<bool> TestValidityAsync(IProxyTest test, int timeoutSeconds = 30)
{
try
{
var req = WebRequest.Create(test.URL);
req.Proxy = new WebProxy(this.ToString());
var respBody = await WebUtility.GetResponseStringAsync(req).TimeoutAfter(new TimeSpan(0, 0, timeoutSeconds));
if (respBody.Contains(test.Validation))
{
return true;
}
else
{
return false;
}
}
catch (Exception)
{
return false;
}
}
So I found a working solution, it is to add the TPL Dataflow NuGet package to my project and then use the TransformBlock class. When I do this, my UI stays very responsive even if I am processing tons of concurrent requests that often throw exceptions. The code below is proof of concept, I will update it when I translate it to work with my project.
Source: Throttling asynchronous tasks
private async void button1_Click(object sender, EventArgs e)
{
var downloader = new TransformBlock<string, WebResponse>(
url => Download(url),
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 200 }
);
var buffer = new BufferBlock<WebResponse>();
downloader.LinkTo(buffer);
var urls = new List<string>();
for (int i = 0; i < 100000; i++)
{
urls.Add($"http://example{i}.com");
}
foreach (var url in urls)
downloader.Post(url);
//or await downloader.SendAsync(url);
downloader.Complete();
await downloader.Completion;
IList<WebResponse> responses;
if (buffer.TryReceiveAll(out responses))
{
//process responses
}
}
private WebResponse Download(string url)
{
WebResponse resp = null;
try
{
var req = WebRequest.Create(url);
resp = req.GetResponse();
}
catch (Exception)
{
}
return resp;
}
}
I am trying to download minecraft files libraries and assets using listbox to select version then download by click on the button but when I click on the button I get this error
"System.FormatException: 'Input string was not in a correct format.'"
on await MCDownload(files, ctoken.Token);
please reply what should I do.
Thanks!
private async void LaunchMinecraft1_Click(object sender, RoutedEventArgs e)
{
if (Directory.Exists(jsonloc + #"\versions\" + versionsList.SelectedItem.ToString()))
{
MessageBox.Show("Version already exists");
return;
}
ctoken = new CancellationTokenSource();
var files = await GetFiles(versionsList.SelectedItem.ToString(), totalPercentage.Content);
await MCDownload(files, ctoken.Token);
}
public List<string[]> urls = new List<string[]>();
public async Task MCDownload(List<string[]>urls, CancellationToken _ctsblock)
{
totalMB = 0;
_cts = new CancellationTokenSource();
sw.Start();
int count = urls.Count;
if (urls != null && urls.Count != 0)
{
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += (s, e) =>
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
progressBar.Visibility = Visibility.Visible;
downloadedMB.Content = string.Format("{0} MB", ((totalMB / 1024f) / 1024f).ToString("0.00"));
}));
};
myTimer.Interval = 100; // 1000 ms is one second
myTimer.Start();
ServicePointManager.DefaultConnectionLimit = Int32.Parse(Settings.Default["download_threads"].ToString());
var block = new ActionBlock<string[]>(async url =>
{
try
{
await DownloadLibraries(url);
}
catch (WebException) { }
catch (OperationCanceledException) { }
catch (Exception e)
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
MessageBox.Show("There may have been some errors while downloading the game. It shouldn't be a problem though. If you experience any issue, try to reinstall again or contact us!");
}));
Console.WriteLine("ERRORE IN" + url[3] + "\r\n" + e);
}
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Int32.Parse(Properties.Settings.Default["download_threads"].ToString()), CancellationToken = _ctsblock });
foreach (var url in urls)
{
block.Post(url);
}
block.Complete();
try
{
await block.Completion;
}
catch (TaskCanceledException)
{
return;
}
myTimer.Stop();
Application.Current.Dispatcher.Invoke(new Action(() =>
{
downloadedMB.Content = null;
}));
progressBar.Value = 100;
progressBar.Visibility = Visibility.Hidden;
return;
}
}
I having a little issue reading data from Nave32 Flight Controller, I'm able to send data to the card using the SerialDevice class but when the LoadAsync Method is call and there is no more data to read the app hung and does not move forward, there is not exception during the execution of the process. I look at the app state and there is a bunch a task block and I'm not sure why. See image below
UPDATE
Firmware source code is here
here is my example code
namespace Apps.Receiver
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.dataRecived.Text = DateTime.Now.ToString();
}
private async Task readAsync(SerialDevice serialPort)
{
string data = string.Empty;
using (var dataReaderObject = new DataReader(serialPort.InputStream))
{
try
{
dataReaderObject.InputStreamOptions = InputStreamOptions.None;
var hasData = true;
while (hasData)
{
var bytesRead = await dataReaderObject.LoadAsync(serialPort.DataBits);
if (bytesRead > 0)
data += dataReaderObject.ReadString(bytesRead);
else
hasData = false;
}
}
catch (Exception ex)
{
status.Text = "reading data fail: " + ex.Message;
closeDevice(serialPort);
}
}
dataRecived.Text = data;
}
private async void sendData_Click(object sender, RoutedEventArgs e)
{
var serialPort = await getSerialDevice("COM3");
if (dataToSend.Text.Length != 0)
{
using (var dataWriteObject = new DataWriter(serialPort.OutputStream))
{
try
{
if (dataToSend.Text.Equals("#", StringComparison.CurrentCultureIgnoreCase))
dataWriteObject.WriteString(dataToSend.Text);
else
dataWriteObject.WriteString(dataToSend.Text + "\n");
var bytesWritten = await dataWriteObject.StoreAsync();
if (bytesWritten > 0)
{
status.Text = dataToSend.Text + ", ";
status.Text += "bytes written successfully!";
}
await readAsync(serialPort);
}
catch (Exception ex)
{
status.Text = "writing data fail: " + ex.Message;
}
}
closeDevice(serialPort);
}
else
{
status.Text = "Enter the text you want to write and then click on 'WRITE'";
}
}
private void closeDevice(SerialDevice device)
{
device.Dispose();
device = null;
}
private async Task<SerialDevice> getSerialDevice(string portName)
{
var aqs = SerialDevice.GetDeviceSelector("COM3");
var devices = await DeviceInformation.FindAllAsync(aqs);
if (devices.Count == 0)
throw new Exception("Unablet to connect to device");
var serialPort = await SerialDevice.FromIdAsync(devices[0].Id);
if (serialPort == null)
throw new Exception("Unablet to Open to port " + portName);
serialPort.BaudRate = 115200;
serialPort.DataBits = 8;
return serialPort;
}
}
}
See this example, try if it helps doing it like this:
await reader.LoadAsync(8192);
while (reader.UnconsumedBufferLength > 0)
{
strBuilder.Append(reader.ReadString(reader.UnconsumedBufferLength));
await reader.LoadAsync(8192);
}