C# Facing problem to read ajax data using web browser control - c#

This is a web site https://www.wsj.com/news/types/newsplus whose data is getting loaded by ajax at runtime. i have to read all article title text. from morning i tried lots of code but still no code worked because data is getting load by ajax.
This is my code which i tried.
HtmlDocument hd = GetHtmlAjax(new Uri("https://www.wsj.com/news/types/newsplus"), 300, true);
ParseData(hd);
HtmlElementCollection main_element = hd.GetElementsByTagName("h3");
if (main_element != null)
{
foreach (HtmlElement element in main_element)
{
string cls = element.GetAttribute("className");
if (String.IsNullOrEmpty(cls) || !cls.Equals("WSJTheme--headline--unZqjb45 undefined WSJTheme--heading-3--2z_phq5h typography--serif-display--ZXeuhS5E"))
continue;
HtmlElementCollection childDivs = element.Children.GetElementsByName("a");
foreach (HtmlElement childElement in childDivs)
{
//grab links and other stuff same way
string linktxt = childElement.InnerText;
}
}
}
WebBrowser wb = null;
public HtmlDocument GetHtmlAjax(Uri uri, int AjaxTimeLoadTimeOut,bool loadurl)
{
if (loadurl)
{
wb = new WebBrowser();
wb.ScriptErrorsSuppressed = true;
wb.Navigate(uri);
}
while (wb.ReadyState != WebBrowserReadyState.Complete)
Application.DoEvents();
Thread.Sleep(AjaxTimeLoadTimeOut);
Application.DoEvents();
return wb.Document;
}
i follow many links to handle this issue but fail. these are the links i followed.
htmlagilitypack and dynamic content issue
Get HTML in C# from page that Loads Dynamic Data
Retrieve ajax/JavaScript return results from webpage in c#
How to extract dynamic ajax content from a web page
please some tell me what to change in my code to parse title link text. thanks
Post code from #aepot
private static HttpClient client = new HttpClient();
private static async Task<T> GetJsonPageAsync<T>(string url)
{
using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
string text = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(text);
}
}
private async void button1_Click(object sender, EventArgs e)
{
try
{
dynamic newsList = await GetJsonPageAsync<dynamic>("https://www.wsj.com/news/types/newsplus?id={%22query%22:%22type:=\\%22NewsPlus\\%22%22,%22db%22:%22wsjie,blog,interactivemedia%22}&type=search_collection");
List<Task<dynamic>> tasks = new List<Task<dynamic>>();
foreach (dynamic item in newsList.collection)
{
string strUrl = "https://www.wsj.com/news/types/newsplus?id=" + item.id + "&type=article";
tasks.Add(GetJsonPageAsync<dynamic>(strUrl));
//tasks.Add(GetJsonPageAsync<dynamic>($"https://www.wsj.com/news/types/newsplus?id={item.id}&type=article"));
}
dynamic[] newsDataList = await Task.WhenAll(tasks);
foreach (dynamic newItem in newsDataList)
{
//Console.WriteLine(newItem.data.headline);
//Console.WriteLine(newItem.data.url);
txtData.Text += newItem.data.headline + System.Environment.NewLine;
txtData.Text += new string('-', 200); + System.Environment.NewLine;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

AJAX is simple GET or POST request.
Using regular Browser dev tools I've found that page sends simple GET request and receive JSON data. JSON can be deserealized or explored via reader.
For JSON parsing i used Newtonsoft.Json NuGet package
Here's simple example based on WinForms app.
public partial class Form1 : Form
{
private static readonly HttpClient client = new HttpClient();
private async Task<T> GetJsonPageAsync<T>(string url)
{
using (HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
{
response.EnsureSuccessStatusCode();
string text = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(text);
}
}
public Form1()
{
InitializeComponent();
ServicePointManager.DefaultConnectionLimit = 10; // to make it faster
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
}
private async void button1_Click(object sender, EventArgs e)
{
try
{
dynamic newsList = await GetJsonPageAsync<dynamic>("https://www.wsj.com/news/types/newsplus?id={%22query%22:%22type:=\\%22NewsPlus\\%22%22,%22db%22:%22wsjie,blog,interactivemedia%22}&type=search_collection");
List<Task<dynamic>> tasks = new List<Task<dynamic>>();
foreach (dynamic item in newsList.collection)
{
tasks.Add(GetJsonPageAsync<dynamic>($"https://www.wsj.com/news/types/newsplus?id={item.id}&type=article"));
}
dynamic[] newsDataList = await Task.WhenAll(tasks);
foreach (dynamic newItem in newsDataList)
{
textBox1.Text += newItem.data.headline + Environment.NewLine;
textBox1.Text += new string('-', 200) + Environment.NewLine;
}
}
catch (Exception ex)
{
textBox1.Text = ex.Message;
}
}
}
UPD: Added fix for .NET Framework 4.5.2

Related

Why first click event of button not working

I have app(net4.7.2) like this:
Program is simple, when user presses OK, im sending request to steam market to get informations about item which user entered (item steam market url) to textbox.
But when im trying to send request, first click event of button not working:
private void btnOK_Click(object sender, EventArgs e)
{
if (txtItemURL.Text.StartsWith("https://steamcommunity.com/market/listings/730/") == true)
{
Helpers.Helper.BuildURL(txtItemURL.Text);
SteamMarketItem SMI = Helpers.Helper.GetItemDetails();
lblPrice.Text = SMI.LowestPrice.ToString() + "$";
pbItemImage.ImageLocation = SMI.ImagePath;
Helpers.Helper.Kontrollar_BerpaEt();
}
else
{
Helpers.Helper.Kontrollar_SifirlaYanlisDaxilEdilib();
}
}
Method GetItemDetails():
public static SteamMarketItem GetItemDetails()
{
WinForms.Control.CheckForIllegalCrossThreadCalls = false;
Task.Run(() =>
{
try
{
using (HttpClient client = new HttpClient())
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
/* Get item info: */
var ResultFromEndpoint1 = client.GetAsync(ReadyEndpointURL1).Result;
var Json1 = ResultFromEndpoint1.Content.ReadAsStringAsync().Result;
dynamic item = serializer.Deserialize<object>(Json1);
marketItem.LowestPrice = float.Parse(((string)item["lowest_price"]).Replace("$", "").Replace(".", ","));
/* Get item image: */
var ResultFromEndpoint2 = client.GetAsync(ReadyEndPointURL2).Result;
var Json2 = ResultFromEndpoint2.Content.ReadAsStringAsync().Result;
var html = ((dynamic)serializer.Deserialize<object>(Json2))["results_html"];
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
marketItem.ImagePath = htmlDoc.DocumentNode.SelectSingleNode("//img[#class='market_listing_item_img']").Attributes["src"].Value + ".png";
Kontrollar_BerpaEt();
}
}
catch
{
Kontrollar_SifirlaYanlisDaxilEdilib();
}
});
return marketItem;
}
Class SteamMarketItem:
public class SteamMarketItem
{
public string ImagePath { get; set; }
public float LowestPrice { get; set; }
}
When im using Task.Run() first click not working, without Task.Run() working + but main UI thread stopping when request not finished.
I have no idea why this happens, I cant find problem fix myself, I will be glad to get help from you. Thanks.
If you want to use async you need to change your event handler to async so you can use await, please see the following:
1. Change your Event handler to async void, async void is acceptable on event handler methods, you should try to use async Task in place of async void in most other cases, so change your method signature to the following:
private async void btnOK_Click(object sender, EventArgs e)
{
if (txtItemURL.Text.StartsWith("https://steamcommunity.com/market/listings/730/") == true)
{
Helpers.Helper.BuildURL(txtItemURL.Text);
//here we use await to await the task
SteamMarketItem SMI = await Helpers.Helper.GetItemDetails();
lblPrice.Text = SMI.LowestPrice.ToString() + "$";
pbItemImage.ImageLocation = SMI.ImagePath;
Helpers.Helper.Kontrollar_BerpaEt();
}
else
{
Helpers.Helper.Kontrollar_SifirlaYanlisDaxilEdilib();
}
}
2. You shouldn't need to use Task.Run, HttpClient exposes async methods and you can make the method async, also, calling .Result to block on an async method is typically not a good idea and you should make the enclosing method async so you can utilize await:
//Change signature to async and return a Task<T>
public async static Task<SteamMarketItem> GetItemDetails()
{
WinForms.Control.CheckForIllegalCrossThreadCalls = false;
//what is marketItem?? Where is it declared?
try
{
using (HttpClient client = new HttpClient())
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
/* Get item info: */
var ResultFromEndpoint1 = await client.GetAsync(ReadyEndpointURL1);
var Json1 = await ResultFromEndpoint1.Content.ReadAsStringAsync();
dynamic item = serializer.Deserialize<object>(Json1);
marketItem.LowestPrice = float.Parse(((string)item["lowest_price"]).Replace("$", "").Replace(".", ","));
/* Get item image: */
var ResultFromEndpoint2 = await client.GetAsync(ReadyEndPointURL2);
var Json2 = await ResultFromEndpoint2.Content.ReadAsStringAsync();
var html = ((dynamic)serializer.Deserialize<object>(Json2))["results_html"];
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
marketItem.ImagePath = htmlDoc.DocumentNode.SelectSingleNode("//img[#class='market_listing_item_img']").Attributes["src"].Value + ".png";
Kontrollar_BerpaEt();
}
}
catch
{
Kontrollar_SifirlaYanlisDaxilEdilib();
}
//what is marketItem?? Where is it declared?
return marketItem;
}

UWP IOT-Core App System.Exception: The application called an interface that was marshalled for a different thread

I'm stuck with an App that is running on Windows 10 IoT Core. All Classes are working fine, except for the one that is creating a CSV File via JSON and is supposed to send it as an Email.
When the Code reaches the "ReturnToMainPage()" Function the Exception "System.Exception: The application called an interface that was marshalled for a different thread" is thrown.
The "funny" thing is, the Mail is being send and i recieve it but the Program won't switch to back to the Main Page as intendet after sending the Email.
Here is the Code of the Class:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using EASendMail;
namespace PratschZahlstation
{
public sealed partial class MailChoice : Page
{
private TextBlock _headerText;
private ComboBox _mailComboBox;
private Button _execute;
private Button _abort;
private EnDecode _coder = EnDecode.get_EnDecodeSingleton();
private string _mailto = null;
public MailChoice()
{
this.InitializeComponent();
Init();
}
private void Init()
{
_headerText = HeaderText;
_mailComboBox = MailAdresses;
_mailComboBox.Items.Add("---");
_mailComboBox.Items.Add("dummy#mail.com");
_mailComboBox.SelectedIndex = 0;
_execute = DoFunction;
_abort = DoExit;
}
private void DoFunction_Click(object sender, RoutedEventArgs e)
{
string selectedMail = this._mailComboBox.SelectedItem.ToString();
if(selectedMail == "---")
{
_headerText.Text = "Bitte eine Emailadresse aus der Liste auswählen.";
}
else
{
_headerText.Text = "CSV wird erstellt und per Mail versendet!";
_execute.IsEnabled = false;
_abort.IsEnabled = false;
_mailComboBox.IsEnabled = false;
_mailto = selectedMail;
DateTime date = DateTime.Now;
string strippedDate = date.ToString("yyyy-MM-dd") + " 00:00:01";
GetDataForCSV(strippedDate);
}
}
private async void GetDataForCSV(string dateAsString)
{
string correctedDate = "2019-07-01 00:00:01";//dateAsString;
string date = _coder.Base64Encode(correctedDate);
HttpClient _client = new HttpClient();
Uri _uri = new Uri("URI TO JSON-API");
_client.BaseAddress = _uri;
var request = new HttpRequestMessage(HttpMethod.Post, _uri);
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("mode", "10"));
keyValues.Add(new KeyValuePair<string, string>("date", date));
request.Content = new FormUrlEncodedContent(keyValues);
var response = await _client.SendAsync(request);
string sContent = await response.Content.ReadAsStringAsync();
keyValues = null;
if (sContent != null)
{
byte[] bytes = Encoding.UTF8.GetBytes(sContent);
string json = Encoding.UTF8.GetString(bytes);
if (!json.Contains("success"))
{
List<CSV_SQL_Json_Object> _Json = JsonConvert.DeserializeObject<List<CSV_SQL_Json_Object>>(json);
response.Dispose();
request.Dispose();
_client.Dispose();
if (_Json.Count == 0)
{
}
else
{
CreateCSV(_Json);
}
}
else
{
List<JSON_Status> _Json = JsonConvert.DeserializeObject<List<JSON_Status>>(json);
_headerText.Text = "Es ist der Folgender Fehler aufgetreten - Errorcode: \"" + _coder.Base64Decode(_Json[0].success) + "\"\r\nFehlermeldung: \"" + _coder.Base64Decode(_Json[0].message) + "\"";
_Json.Clear();
response.Dispose();
request.Dispose();
_client.Dispose();
}
}
}
private async void CreateCSV(List<CSV_SQL_Json_Object> contentForCSV)
{
DateTime date = DateTime.Now;
string csvName = date.ToString("yyyy-MM-dd") + ".csv";
StorageFolder storageFolder = KnownFolders.MusicLibrary;
StorageFile csvFile = await storageFolder.CreateFileAsync(csvName, CreationCollisionOption.OpenIfExists).AsTask().ConfigureAwait(false);
await FileIO.WriteTextAsync(csvFile, "Column1;Column2;Column3;Column4;\n");
foreach (var item in contentForCSV)
{
await FileIO.AppendTextAsync(csvFile, _coder.Base64Decode(item.Object1) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object2)) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object3)) + ";" + _coder.aesDecrypt(_coder.Base64Decode(item.Object4)) + "\n");
}
SendEmail(_mailto, csvName);
}
private async void SendEmail(string mailto, string csvName)
{
try
{
SmtpMail oMail = new SmtpMail("Mail");
SmtpClient oSmtp = new SmtpClient();
oMail.From = new MailAddress("noreply#dummy.com");
oMail.To.Add(new MailAddress(mailto));
oMail.Subject = "The Subject";
oMail.HtmlBody = "<font size=5>MailText</font>";
StorageFile file = await KnownFolders.MusicLibrary.GetFileAsync(csvName).AsTask().ConfigureAwait(false);
string attfile = file.Path;
Attachment oAttachment = await oMail.AddAttachmentAsync(attfile);
SmtpServer oServer = new SmtpServer("mail.dummy.com");
oServer.User = "dummyuser";
oServer.Password = "dummypass";
oServer.Port = 587;
oServer.ConnectType = SmtpConnectType.ConnectSSLAuto;
await oSmtp.SendMailAsync(oServer, oMail);
}
catch (Exception ex)
{
string error = ex.ToString();
_abort.IsEnabled = true;
}
ReturnToMainPage(); //This is where the Error Happens
}
private void ReturnToMainPage()
{
this.Frame.Navigate(typeof(MainPage));
}
private void DoExit_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(MainPage));
}
}
}
This could be an Threading issue. Navigation is only possible on the main-Thread.
You may want to try to marshal the call in:
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
}
);
Source:
The application called an interface that was marshalled for a different thread - Windows Store App
Like Tobonaut said, you can use the Dispatcher.RunAsync to call the Navigation, it worked.
But your problem may not be this.
I copied your code and reproduced your problem and found that you have problems with the calls to read and write files:
// Your code
StorageFile csvFile = await storageFolder.CreateFileAsync(csvName, CreationCollisionOption.OpenIfExists).AsTask().ConfigureAwait(false);
StorageFile file = await KnownFolders.MusicLibrary.GetFileAsync(csvName).AsTask().ConfigureAwait(false);
The Navigation will be work if you delete the .AsTask().ConfigureAwait(false).
Best regards.

How to make webclient download file again if failed?

I'm trying to download a list of links of images to my server (Up to 40 links) using foreach.
In my case sometimes the link exists but I don't know why it's going to catch and cancel the download of the next link. Maybe it needs to wait for a little? because when I debug the app I see that the link was the application skipped and went to catch was available but sometimes it's open after few seconds in my browser so the response time from the server I trying to download sometimes need more time to load and open the link.
string newPath = "~/data/" + model.PostID + "/" + name + "/";
//test1 is a list of links
foreach (var item1 in test1)
{
HttpWebRequest request = WebRequest.Create(item1) as HttpWebRequest; request.Method = "HEAD";
try
{
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
var webClient = new WebClient();
string path = newPath + i + ".jpg";
webClient.DownloadFileAsync(new Uri(item1), Server.MapPath(path));
string newlinks = "https://example.com/data/" + chapter.PostID + "/" + name + "/" + i + ".jpg";
allimages = allimages + newlinks + ',';
response.Close();
i++;
}
}
catch
{
break;
}
}
Now my main goal is to fix this issue but as I saw in debugging:
The Images Links I'm trying to download exists
Sometimes Need More Time to response
So How I can fix this ? when download cancel and a link exists, what I should do?
you can use this example:
class WebClientUtility : WebClient
{
public int Timeout { get; set; }
public WebClientUtility() : this(60000) { }
public WebClientUtility(int timeout)
{
this.Timeout = timeout;
}
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
if (request != null)
{
request.Timeout = Timeout;
}
return request;
}
}
//
public class DownloadHelper : IDisposable
{
private WebClientUtility _webClient;
private string _downloadUrl;
private string _savePath;
private int _retryCount;
public DownloadHelper(string downloadUrl, string savePath)
{
_savePath = savePath;
_downloadUrl = downloadUrl;
_webClient = new WebClientUtility();
_webClient.DownloadFileCompleted += ClientOnDownloadFileCompleted;
}
public void StartDownload()
{
_webClient.DownloadFileAsync(new Uri(_downloadUrl), _savePath);
}
private void ClientOnDownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error != null)
{
_retryCount++;
if (_retryCount < 3)
{
_webClient.DownloadFileAsync(new Uri(_downloadUrl), _savePath);
}
else
{
Console.WriteLine(e.Error.Message);
}
}
else
{
_retryCount = 0;
Console.WriteLine($"successfully download: # {_downloadUrl} to # {_savePath}");
}
}
public void Dispose()
{
_webClient.Dispose();
}
}
//
class Program
{
private static void Main(string[] args)
{
for (int i = 0; i < 100; i++)
{
var downloadUrl = $#"https://example.com/mag-{i}.pdf";
var savePath = $#"D:\DownloadFile\FileName{i}.pdf";
DownloadHelper downloadHelper = new DownloadHelper(downloadUrl, savePath);
downloadHelper.StartDownload();
}
Console.ReadLine();
}
}
to fix timeout problem you can create a derived class and set the timeout property of the base WebRequest class and
for retry you can use the DownloadFileCompleted event of the WebClient and implement your retry pattern there
You're using the async version of 'DownloadFileAsync'. However you're not awaiting the call, that leaves a mess with unpredicted behaviour.
Make your method async and then use this:
await webClient.DownloadFileAsync(new Uri(item1), Server.MapPath(path));
This Solved my case:
await Task.Run(() =>
{
webClient.DownloadFileAsync(new Uri(item1), Server.MapPath(path));
});

The process cannot access the file because it is being used by another process

I am running a program where a file gets uploaded to a folder in IIS,and then is processed to extract some values from it. I use a WCF service to perform the process, and BackgroundUploader to upload the file to IIS. However, after the upload process is complete, I get the error "The process cannot access the file x because it is being used by another process." Based on similar questions asked here, I gathered that the file concerned needs to be in a using statement. I tried to modify my code to the following, but it didn't work, and I am not sure if it is even right.
namespace App17
{
public sealed partial class MainPage : Page, IDisposable
{
private CancellationTokenSource cts;
public void Dispose()
{
if (cts != null)
{
cts.Dispose();
cts = null;
}
GC.SuppressFinalize(this);
}
public MainPage()
{
this.InitializeComponent();
cts = new CancellationTokenSource();
}
public async void Button_Click(object sender, RoutedEventArgs e)
{
try
{
Uri uri = new Uri(serverAddressField.Text.Trim());
FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add("*");
StorageFile file = await picker.PickSingleFileAsync();
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
GlobalClass.filecontent = file.Name;
GlobalClass.filepath = file.Path;
BackgroundUploader uploader = new BackgroundUploader();
uploader.SetRequestHeader("Filename", file.Name);
UploadOperation upload = uploader.CreateUpload(uri, file);
await HandleUploadAsync(upload, true);
stream.Dispose();
}
}
catch (Exception ex)
{
string message = ex.ToString();
var dialog = new MessageDialog(message);
await dialog.ShowAsync();
Log(message);
}
}
private void CancelAll(object sender, RoutedEventArgs e)
{
Log("Canceling all active uploads");
cts.Cancel();
cts.Dispose();
cts = new CancellationTokenSource();
}
private async Task HandleUploadAsync(UploadOperation upload, bool start)
{
try
{
Progress<UploadOperation> progressCallback = new Progress<UploadOperation>(UploadProgress);
if (start)
{
await upload.StartAsync().AsTask(cts.Token, progressCallback);
}
else
{
// The upload was already running when the application started, re-attach the progress handler.
await upload.AttachAsync().AsTask(cts.Token, progressCallback);
}
ResponseInformation response = upload.GetResponseInformation();
Log(String.Format("Completed: {0}, Status Code: {1}", upload.Guid, response.StatusCode));
cts.Dispose();
}
catch (TaskCanceledException)
{
Log("Upload cancelled.");
}
catch (Exception ex)
{
string message = ex.ToString();
var dialog = new MessageDialog(message);
await dialog.ShowAsync();
Log(message);
}
}
private void Log(string message)
{
outputField.Text += message + "\r\n";
}
private async void LogStatus(string message)
{
var dialog = new MessageDialog(message);
await dialog.ShowAsync();
Log(message);
}
private void UploadProgress(UploadOperation upload)
{
BackgroundUploadProgress currentProgress = upload.Progress;
MarshalLog(String.Format(CultureInfo.CurrentCulture, "Progress: {0}, Status: {1}", upload.Guid,
currentProgress.Status));
double percentSent = 100;
if (currentProgress.TotalBytesToSend > 0)
{
percentSent = currentProgress.BytesSent * 100 / currentProgress.TotalBytesToSend;
}
MarshalLog(String.Format(CultureInfo.CurrentCulture,
" - Sent bytes: {0} of {1} ({2}%), Received bytes: {3} of {4}", currentProgress.BytesSent,
currentProgress.TotalBytesToSend, percentSent, currentProgress.BytesReceived, currentProgress.TotalBytesToReceive));
if (currentProgress.HasRestarted)
{
MarshalLog(" - Upload restarted");
}
if (currentProgress.HasResponseChanged)
{
MarshalLog(" - Response updated; Header count: " + upload.GetResponseInformation().Headers.Count);
}
}
private void MarshalLog(string value)
{
var ignore = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
Log(value);
});
}
}
}
After this is done, the file name is sent to a WCF service which will access and process the uploaded file to extract certain values. It is at this point I receive the error. I would truly appreciate some help.
public async void Extract_Button_Click(object sender, RoutedEventArgs e)
{
ServiceReference1.Service1Client MyService = new ServiceReference1.Service1Client();
string filename = GlobalClass.filecontent;
string filepath = #"C:\Users\R\Documents\Visual Studio 2015\Projects\WCF\WCF\Uploads\"+ filename;
bool x = await MyService.ReadECGAsync(filename, filepath);
}
EDIT: Code before I added the using block
try
{
Uri uri = new Uri(serverAddressField.Text.Trim());
FileOpenPicker picker = new FileOpenPicker();
picker.FileTypeFilter.Add("*");
StorageFile file = await picker.PickSingleFileAsync();
GlobalClass.filecontent = file.Name;
GlobalClass.filepath = file.Path;
BackgroundUploader uploader = new BackgroundUploader();
uploader.SetRequestHeader("Filename", file.Name);
UploadOperation upload = uploader.CreateUpload(uri, file);
await HandleUploadAsync(upload, true);
}
When you work with stream writers you actually create a process, which you can close it from task manager. And after stream.Dispose() put stream.Close().
This should solve your problem.
You should also close the stream that writes the file to disk (look at your implementation of CreateUpload).
i got such error in DotNet Core 2 using this code:
await file.CopyToAsync(new FileStream(fullFileName, FileMode.Create));
counter++;
and this is how I managed to get rid of message (The process cannot access the file x because it is being used by another process):
using (FileStream DestinationStream = new FileStream(fullFileName, FileMode.Create))
{
await file.CopyToAsync(DestinationStream);
counter++;
}

How do I create a background thread

I'm currently working toward a mobile android application. The main thing that this app will have trouble with for load times is a Webservice json string that at this current stage is taking too long to load and sometimes causing the app to force close (stalling for too long).
Splash -> MainActivity -> HomeActivity This is how our application starts.
First we display a Splash, and behind that we run the MainActivity, which consists of the following code:
public class HomeActivity : Activity
{
NewsObject[] news;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
var request = HttpWebRequest.Create(string.Format(#"http://rapstation.com/webservice.php"));
request.ContentType = "application/json";
request.Method = "GET";
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
Console.Out.WriteLine("Error fetching data. Server returned status code: {0}", response.StatusCode);
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
var content = reader.ReadToEnd();
if(string.IsNullOrWhiteSpace(content)) {
Console.Out.WriteLine("Response contained empty body...");
Toast toast = Toast.MakeText (this, "No Connection to server, Application will now close", ToastLength.Short);
toast.Show ();
}
else {
news = JsonConvert.DeserializeObject<NewsObject[]>(content);
}
}
Console.Out.WriteLine ("Now: \r\n {0}", news[0].title);
}
var list = FindViewById<ListView> (Resource.Id.list);
list.Adapter = new HomeScreenAdapter (this, news);
list.ItemClick += OnListItemClick;
var Listen = FindViewById<Button> (Resource.Id.btnListen);
var Shows = FindViewById<Button> (Resource.Id.btnShows);
Listen.Click += (sender, e) => {
var second = new Intent (this, typeof(RadioActivity));
StartActivity (second);
};
Shows.Click += (sender, e) => {
var second = new Intent (this, typeof(ShowsActivity));
StartActivity (second);
};
}
protected void OnListItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
var listView = sender as ListView;
var t = news[e.Position];
var second = new Intent (this, typeof(NewsActivity));
second.PutExtra ("newsTitle", t.title);
second.PutExtra ("newsBody", t.body);
second.PutExtra ("newsImage", t.image);
second.PutExtra ("newsCaption", t.caption);
StartActivity (second);
Console.WriteLine("Clicked on " + t.title);
}
}
The problem I am running into is the app will stick on the Splash page and the Application output will tell me that I am running too much on the Main thread.
What is a way to separate the download request to work in the background?
private class myTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
}
#Override
protected Void doInBackground(Void... params) {
// Runs on the background thread
return null;
}
#Override
protected void onPostExecute(Void res) {
}
}
and to run it
new myTask().execute();
Yes there is, you need to use AsyncTask, this should help too.
If the .Net/Mono version you're using supports async/await then you can simply do
async void DisplayNews()
{
string url = "http://rapstation.com/webservice.php";
HttpClient client = new HttpClient();
string content = await client.GetStringAsync(url);
NewsObject[] news = JsonConvert.DeserializeObject<NewsObject[]>(content);
//!! Your code to add news to some control
}
if Not, then you can use Task's
void DisplayNews2()
{
string url = "http://rapstation.com/webservice.php";
Task.Factory.StartNew(() =>
{
using (var client = new WebClient())
{
string content = client.DownloadString(url);
return JsonConvert.DeserializeObject<NewsObject[]>(content);
}
})
.ContinueWith((task,y) =>
{
NewsObject[] news = task.Result;
//!! Your code to add news to some control
},null,TaskScheduler.FromCurrentSynchronizationContext());
}

Categories