I am working on Windows Phone 8 project. In my project there are 10 Events with 10 EventHandlers ReverseGeocodeQuery_QueryCompleted (1 to 10). When first EventHandler is completed it turn on second event.
What should I implement to manage those Events without so much code.
code
myReverseGeocodeQuery = new ReverseGeocodeQuery();
myReverseGeocodeQuery.GeoCoordinate = mySimulationCoordinates.ElementAt(0);
myReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted_1;
myReverseGeocodeQuery.QueryAsync();
private void ReverseGeocodeQuery_QueryCompleted_1(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
{
if (e.Error == null)
{
if (e.Result.Count > 0)
{
MapAddress address = e.Result[0].Information.Address;
label8txt.Text = address.City.ToString() + "\n" + address.Street.ToString();
StringBuilder str = new StringBuilder();
str.AppendLine("Pierwszy");
str.AppendLine("11" + address.HouseNumber);
str.AppendLine("17" + address.Street);
MessageBox.Show(str.ToString());
}
myReverseGeocodeQuery = new ReverseGeocodeQuery();
myReverseGeocodeQuery.GeoCoordinate = mySimulationCoordinates.ElementAt(1);
myReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted_2;
myReverseGeocodeQuery.QueryAsync();
}
}
private void ReverseGeocodeQuery_QueryCompleted_2(object sender, QueryCompletedEventArgs<IList<MapLocation>> e)
{
if (e.Error == null)
{
if (e.Result.Count > 0)
{
MapAddress address = e.Result[0].Information.Address;
label8txt.Text = address.City.ToString() + "\n" + address.Street.ToString();
StringBuilder str = new StringBuilder();
str.AppendLine("Drugi");
str.AppendLine("11" + address.HouseNumber);
str.AppendLine("17" + address.Street);
MessageBox.Show(str.ToString());
myReverseGeocodeQuery = new ReverseGeocodeQuery();
myReverseGeocodeQuery.GeoCoordinate = mySimulationCoordinates.ElementAt(2);
myReverseGeocodeQuery.QueryCompleted += ReverseGeocodeQuery_QueryCompleted_3;
myReverseGeocodeQuery.QueryAsync();
}
}
}
Example Solution 1
public class DataContainer
{
public string Description { get; set; }
public GeoCoordinate Coordinate { get; set; }
//public List<GeoCoordinate> mySimulationCoordinates { get; set; }
public String EnterSimulation() {
StringBuilder strRet = new StringBuilder();
List<GeoCoordinate> mySimulationCoordinates = new List<GeoCoordinate>();
mySimulationCoordinates.Add(new GeoCoordinate(51.760752, 19.458216));
mySimulationCoordinates.Add(new GeoCoordinate(51.760757, 19.458356));
mySimulationCoordinates.Add(new GeoCoordinate(51.760738, 19.458442));
mySimulationCoordinates.Add(new GeoCoordinate(51.7607, 19.458501));
mySimulationCoordinates.Add(new GeoCoordinate(51.760662, 19.458533));
var descriptions = new[] { "Pierwszy", "Drugi", "Trzeci", "Czwarty", "Piąty" }; //etc
var zipped = mySimulationCoordinates.Zip(descriptions, (coord, desc) => new DataContainer { Description = desc, Coordinate = coord });
int k = zipped.Count();
foreach (var item in zipped)
{
var currentItem = item;
using (var waitHandle = new AutoResetEvent(false))
{
var geocodeQuery = new ReverseGeocodeQuery();
geocodeQuery.GeoCoordinate = item.Coordinate;
geocodeQuery.QueryCompleted += (sender, args) =>
{
if (args.Error == null)
{
if (args.Result.Count > 0)
{
MapAddress address = args.Result[0].Information.Address;
//label8txt.Text = address.City.ToString() + "\n" + address.Street.ToString();
StringBuilder str = new StringBuilder();
str.AppendLine(currentItem.Description);
str.AppendLine("House Number" + address.HouseNumber);
str.AppendLine("Street " + address.Street);
strRet.AppendLine("->");
strRet.Append(str);
waitHandle.Set();
}
}
};
geocodeQuery.QueryAsync();
waitHandle.WaitOne();
}
}
return strRet.ToString();
}
It stuck on 1st item. Is inside and wait ... wait ... can't pass to next element.
Umm... Let's see, shouldn't that be easier?
Warning: untested
public class DataContainer
{
public string Description {get;set;}
public GeoCoordinate Coordinate {get;set;}
}
var descriptions = new[] {"Pierwszy" , "Drugi" , "Trzeci" }; //etc
var zipped = mySimulationCoordinates.Zip(descriptions, (coord, desc) => new DataContainer { Description = desc, Coordinate = coord });
foreach(var item in zipped)
{
var currentItem = item;
using(var waitHandle = new AutoResetEvent(false))
{
var geocodeQuery = new ReverseGeocodeQuery();
geocodeQuery.GeoCoordinate = currentItem.Coordinates;
geocodeQuery.QueryCompleted += (sender, args) => {
if (e.Error == null)
{
if (e.Result.Count > 0)
{
MapAddress address = args.Result[0].Information.Address;
label8txt.Text = address.City.ToString() + "\n" + address.Street.ToString();
StringBuilder str = new StringBuilder();
str.AppendLine(currentItem.Description);
str.AppendLine("11" + address.HouseNumber);
str.AppendLine("17" + address.Street);
MessageBox.Show(str.ToString());
waitHandle.Set();
}
}
};
geoCodeQuery.QueryAsync();
waitHandle.WaitOne();
}
}
That should guarantee you that one event is handled after another in order.
Related
The player can create a room with certain properties that once created I set them and for lobby so that I can then display them in the lobby.
Function to create room:
public void OnCreateRoomButtonClicked()
{
RoomOptions roomOptions = new RoomOptions();
roomOptions.IsOpen = true;
roomOptions.IsVisible = true;
string roomName;
string gameMap;
if (gameMode.Equals("CarMeeting"))
{
gameMap = carMeetingModeMaps[mapIndex].sceneName;
roomName = roomNameCarMeetingModeInputField.text;
roomOptions.MaxPlayers = 4;
}
else
{
gameMap = racingModeMaps[mapIndex].sceneName;
roomName = roomNameRacingModeInputField.text;
roomOptions.MaxPlayers = 2;
}
if (!CheckIfRoomAlreadyExists(roomName))
{
StartCoroutine(EShowWarning());
}
else
{
roomOptions.CustomRoomProperties = new Hashtable();
roomOptions.CustomRoomProperties.Add("GameMap", gameMap);
roomOptions.CustomRoomProperties.Add("GameMode", gameMode);
roomOptions.CustomRoomProperties.Add("RaceMode", raceMode);
roomOptions.CustomRoomProperties.Add("InRace", false);
string[] customLobbyProperties = new string[4];
customLobbyProperties[0] = "GameMap";
customLobbyProperties[1] = "GameMode";
customLobbyProperties[2] = "RaceMode";
customLobbyProperties[3] = "InRace";
roomOptions.CustomRoomPropertiesForLobby = customLobbyProperties;
PhotonNetwork.CreateRoom(roomName, roomOptions, null, null);
}
}
Function display rooms in lobby:
public override void OnRoomListUpdate(List<RoomInfo> roomInfo)
{
Debug.Log("Rooms found " + roomInfo.Count);
bool roomFound = false;
foreach (RoomInfo room in roomInfo)
{
if (room.RemovedFromList)
{
int index = roomUIs.FindIndex(x => x.roomNameString.Equals(room.Name));
if (index != -1)
{
Destroy(roomUIs[index].gameObject);
roomUIs.RemoveAt(index);
}
}
else
{
CMRoomUI cacheRoomUI = roomUIs.Find(x => x.roomNameString.Equals(room.Name));
if (cacheRoomUI != null)
{
if (room.CustomProperties["GameMode"].ToString().Equals("CarMeeting"))
cacheRoomUI.Check(room.Name, (room.PlayerCount + "/" + room.MaxPlayers).ToString(), room.CustomProperties["GameMap"].ToString(), room.CustomProperties["GameMode"].ToString());
else
cacheRoomUI.Check(room.Name, (room.PlayerCount + "/" + room.MaxPlayers).ToString(), room.CustomProperties["GameMap"].ToString(), room.CustomProperties["GameMode"].ToString()
, room.CustomProperties["RacingMode"].ToString());
}
else
{
if (room.IsOpen)
{
CMRoomUI roomUI = Instantiate(roomUIPrefab.gameObject, roomUIParent).GetComponent<CMRoomUI>();
roomUIs.Add(roomUI);
if (room.CustomProperties["GameMode"].ToString().Equals("CarMeeting"))
roomUI.Check(room.Name, (room.PlayerCount + "/" + room.MaxPlayers).ToString(), room.CustomProperties["GameMap"].ToString(), room.CustomProperties["GameMode"].ToString());
else
cacheRoomUI.Check(room.Name, (room.PlayerCount + "/" + room.MaxPlayers).ToString(), room.CustomProperties["GameMap"].ToString(), room.CustomProperties["GameMode"].ToString()
, room.CustomProperties["RaceMode"].ToString());
}
}
}
}
if (roomUIs.Count > 0) roomFound = true;
noRoomTextObj.SetActive(!roomFound);
}
After I create a room if another player connects to the looby, I display the cameras visible with those properties, but the property "RaceMode" does not exist.
I'm new to C#. I need to sort my ObservableCollection with four kinds of sorts, but I can't understand how to do that, and my Google searches didn't help.
I thought that I could create a new observable collection like this:
var orderedByNameObservableCollection = performerList.OrderBy(p =\> p.Name);
...but I can't understand how to easily update the table with the new ObservableCollection.
My code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.SizeToContent = SizeToContent.WidthAndHeight;
}
private static string[] Load(string filename)
{
List<string> strings = null;
using (StreamReader sr = new StreamReader(filename))
{
strings = new List<string>();
while (!sr.EndOfStream)
{
strings.Add(sr.ReadLine());
}
}
return strings.ToArray();
}
internal string[] fileRKK;
internal string[] fileAppeals;
private void openFileRKKButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialogRKK = new OpenFileDialog();
if (openFileDialogRKK.ShowDialog() == true)
{
TextBlockRKK.Text = "Выбранный файл: " + Path.GetFileName(openFileDialogRKK.FileName);
fileRKK = Load(openFileDialogRKK.FileName);
}
}
private void openFileAppealsButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialogAppeals = new OpenFileDialog();
if (openFileDialogAppeals.ShowDialog() == true)
{
TextBlockAppeals.Text = "Выбранный файл: " + Path.GetFileName(openFileDialogAppeals.FileName);
fileAppeals = Load(openFileDialogAppeals.FileName);
}
}
Dictionary<string, int> staffRKK = new Dictionary<string, int>();
Dictionary<string, int> staffAppeals = new Dictionary<string, int>();
private Dictionary<string, int> staffGeneral = new Dictionary<string, int>();
ObservableCollection<Performer> performerList = new ObservableCollection<Performer>();
private void dataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.Header = e.Row.GetIndex() + 1;
}
private void WriteInTable()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
//СЛОВАРЬ РКК
if (fileRKK != null)
{
var queryOfRKK = from line in fileRKK
let searchingPerson = line.Split('\t', ';')
select new
{
ResponsiblePerson = (searchingPerson[0] == "Климов Сергей Александрович"
? searchingPerson[1].Replace("(Отв.)", "").Trim()
: searchingPerson[0].Trim()),
};
foreach (var item in queryOfRKK)
{
var value = item.ResponsiblePerson.Trim().Split(' ');
string fio;
if (value.Length == 3)
{
fio = value[0] + " " + value[1].Substring(0, 1) + "." + value[2].Substring(0, 1) + ".".Trim();
}
else
{
fio = item.ResponsiblePerson;
}
if (staffRKK.ContainsKey(fio))
{
staffRKK[fio]++;
}
else
staffRKK.Add(fio, 1);
}
}
//СЛОВАРЬ ОБРАЩЕНИЙ
if (fileAppeals != null)
{
var queryOfAppeals = from line in fileAppeals
let searchingPerson = line.Split('\t', ';')
select new
{
ResponsiblePerson = (searchingPerson[0] == "Климов Сергей Александрович"
? searchingPerson[1].Replace("(Отв.)", "").Trim()
: searchingPerson[0]),
};
foreach (var item in queryOfAppeals)
{
var value = item.ResponsiblePerson.Trim().Split(' ');
string fio;
if (value.Length == 3)
{
fio = value[0] + " " + value[1].Substring(0, 1) + "." + value[2].Substring(0, 1) + ".";
}
else
{
fio = item.ResponsiblePerson;
}
if (staffAppeals.ContainsKey(fio))
{
staffAppeals[fio]++;
}
else
staffAppeals.Add(fio, 1);
}
}
//ОБЩИЙ СЛОВАРЬ
staffGeneral = (from p in staffRKK.Concat(staffAppeals)
group p by p.Key into g
select new { fio = g.Key, Count = g.Sum(kvp => kvp.Value) }).ToDictionary(item => item.fio,
item => item.Count);
foreach (var item in staffRKK)
{
performerList.Add(new Performer
{
Name = item.Key,
CountRKK = item.Value,
CountAppeals =
staffAppeals.ContainsKey(item.Key) ? staffAppeals[item.Key] : 0,
CountGeneral = item.Value + (staffAppeals.ContainsKey(item.Key) ? staffAppeals[item.Key] : 0)
}
);
staffAppeals.Remove(item.Key);
}
foreach (var item2 in staffAppeals)
{
performerList.Add(new Performer { Name = item2.Key, CountAppeals = item2.Value });
}
DataGrid.ItemsSource = performerList.Select(p => new
{
p.Name,
p.CountRKK,
p.CountAppeals,
p.CountGeneral
});
DataGrid.Columns[0].Header = "Ответственный" + Environment.NewLine + "исполнитель";
DataGrid.Columns[1].Header = "Количество" + Environment.NewLine + "неисполненных" + Environment.NewLine +
"входящих документов";
DataGrid.Columns[2].Header = "Количество" + Environment.NewLine + "неисполненных" + Environment.NewLine +
"письменных " + Environment.NewLine + "обращений граждан";
DataGrid.Columns[3].Header = "Общее количество " + Environment.NewLine + "документов и " +
Environment.NewLine + "обращений";
stopWatch.Stop();
TextBlockTime.Text = $"{stopWatch.ElapsedMilliseconds} мс"; ;
}
private void ButtonLoad_Click(object sender, RoutedEventArgs e)
{
if (fileRKK != null && fileAppeals != null)
{
TextBlockTodayDate.Text = $"Дата составления справки: {DateTime.Now.ToShortDateString()}";
Total.Text = $"Не исполнено в срок {performerList.Sum(p => p.CountGeneral)} документов, из них:";
TotalRKK.Text = $"- количество неисполненных входящих документов: {performerList.Sum(p => p.CountRKK)};";
TotalAppeals.Text = $"- количество неисполненных письменных обращений граждан: {performerList.Sum(p => p.CountAppeals)}.";
WriteInTable();
}
else MessageBox.Show("Вы выбрали не все файлы!");
}
/* private void ButtonNameSort_Click(object sender, RoutedEventArgs e)
{
//TODO
WriteInTable();
}
private void ButtonRKKSort_Click(object sender, RoutedEventArgs e)
{
//TODO
WriteInTable();
}
private void ButtonAppealsSort_Click(object sender, RoutedEventArgs e)
{
//TODO
WriteInTable();
}
private void ButtonGeneralSort_Click(object sender, RoutedEventArgs e)
{
//TODO
WriteInTable();
}*/
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
if (DataGrid == null)
{
MessageBox.Show("Нечего выводить!");
return;
}
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Text files (*.txt)|*.txt";
if (saveFileDialog.ShowDialog() == true)
{
using (StreamWriter writer = new StreamWriter(saveFileDialog.FileName, false))
{
writer.WriteLine("Справка о неисполненных документах и обращениях граждан\n");
writer.WriteLine(Total.Text);
writer.WriteLine(TotalRKK.Text);
writer.WriteLine(TotalAppeals.Text);
writer.WriteLine();
writer.WriteLine("{0,4} |{1,20} |{2,11} |{3,16}|{4,13} ",
"№", "Исполнитель", "Кол-во ркк", "Кол-во обращений", "Общее кол-во");
int i = 1;
foreach (var item in performerList)
{
writer.WriteLine("------------------------------------------------------------------------");
writer.WriteLine("{0,4} |{1,20} |{2,11} |{3,15} |{4,13} ",
i++, item.Name, item.CountRKK, item.CountAppeals, item.CountGeneral);
}
}
}
}
}
public class Performer
{
public string Name;
public int CountRKK;
public int CountAppeals;
public int CountGeneral;
}
Maybe you can help me? Maybe you'll tell me the correct ordering or how to write in datagrid the new observable collection?
When you use the OrderBy() function from LINQ, the output is an IEnumerable, which is not an observable collection. So, you need to create an observable collection from the OrderBy() result
var orderedByName = performerList.OrderBy(p => p.Name);
DataGrid.ItemsSource = new ObservableCollection<Performer>(orderedByName);
I have an news aggregator and in debug i have the following:
Skipped 675 frames! The application may be doing too much work on its main thread.
I am loading only from 12 sites. Is there a way to to do all this loading in background without the whole app freezing?
EDIT:
Method to get one news
public async static Task<NewsContent> oneNews(string category,string site)
{
if(sites.Count==0)
addElements();
GetNews gn = new GetNews(site,false);
Random rn = new Random();
var s = await gn.news(rn.Next(0,2));
return s;
}
The GetNews class:
class GetNews
{
string url;
bool isMultiple;
public GetNews(string url,bool isMultiple)
{
this.url = url;
this.isMultiple = isMultiple;
}
public async Task<NewsContent> news(int i)
{
List<NewsContent> feedItemsList = new List<NewsContent>();
try
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
Stream stream = webResponse.GetResponseStream();
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(stream);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
nsmgr.AddNamespace("dc", xmlDocument.DocumentElement.GetNamespaceOfPrefix("dc"));
nsmgr.AddNamespace("content", xmlDocument.DocumentElement.GetNamespaceOfPrefix("content"));
XmlNodeList itemNodes = xmlDocument.SelectNodes("rss/channel/item");
NewsContent feedItem = new NewsContent();
if (itemNodes[i].SelectSingleNode("title") != null)
{
feedItem.title = itemNodes[i].SelectSingleNode("title").InnerText;
}
if (itemNodes[i].SelectSingleNode("link") != null)
{
feedItem.url = itemNodes[i].SelectSingleNode("link").InnerText;
}
if (itemNodes[i].SelectSingleNode("pubDate") != null)
{
var time = itemNodes[i].SelectSingleNode("pubDate").InnerText;
feedItem.time = getHour(time);
}
if (itemNodes[i].SelectSingleNode("description") != null)
{
feedItem.desc = itemNodes[i].SelectSingleNode("description").InnerText;
}
if (itemNodes[i].SelectSingleNode("content:encoded", nsmgr) != null)
{
feedItem.content = itemNodes[i].SelectSingleNode("content:encoded", nsmgr).InnerText;
}
else
{
feedItem.content = feedItem.desc;
}
feedItem.imageURL = getImage(feedItem.content);
var sourcename = url.Split(new[] { "//" }, StringSplitOptions.None)[1];
feedItem.newsSource = sourcename.Split(new[] { "/" }, StringSplitOptions.None)[0];
if (feedItem.content.Contains("<p>"))
{
var shortContent = feedItem.content.Split(new[] { "<p>" }, StringSplitOptions.None)[1];
string finalShortContent = "";
for (int ii = 0; ii < shortContent.Length; ii++)
{
if (ii > 200 && shortContent[ii].Equals(' '))
break;
while (shortContent[ii].Equals('<') || shortContent[ii].Equals('p') || shortContent[ii].Equals('/') || shortContent[ii].Equals('>'))
ii++;
try
{
finalShortContent += shortContent[ii];
}
catch (Exception e)
{
break;
}
}
finalShortContent += "...";
feedItem.shortcontent = finalShortContent;
}
return feedItem;
}
catch (Exception e)
{
return null;
}
}
string getImage(string full)
{
try
{
var code = full.Split(new[] { "src=\"" }, StringSplitOptions.None)[1];
var fin = code.Split(new[] { "\"" }, StringSplitOptions.None)[0];
return fin;
}
catch(Exception e)
{
return null;
}
}
List<int> getHour(string full)
{
try
{
List<int> smh = new List<int>();
var ph = full.Split(new[] { "2020 " }, StringSplitOptions.None)[1];
var hour = ph.Split(new[] { ":" }, StringSplitOptions.None);
smh.Add(Int32.Parse(hour[0]));
smh.Add(Int32.Parse(hour[1]));
var second = hour[2].Split(new[] { " " }, StringSplitOptions.None)[0];
smh.Add(Int32.Parse(second));
return smh;
}catch(Exception)
{
return null;
}
}
}
Try this. It should put the function in another thread
await Task.Run(async () =>
{
//function
});
The exception is happen most of the times but there are times it's working fine.
The exception is always the same
The remote server returned an error: (500) Internal Server Error.
Also the stacktrace is the same:
at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest& request)
at System.Net.WebClient.DownloadData(Uri address)
at System.Net.WebClient.DownloadData(String address)
at SatelliteImages.ExtractImages.ExtractDateAndTime(String baseAddress) in D:\C-Sharp\SatelliteImages\SatelliteImages\SatelliteImages\ExtractImages.cs:line 120
Line 120 is:
var temp = wc.DownloadData("/en");
The method:
public void ExtractDateAndTime(string baseAddress)
{
try
{
var wc = new WebClient();
wc.BaseAddress = baseAddress;
HtmlDocument doc = new HtmlDocument();
var temp = wc.DownloadData("/en");
doc.Load(new MemoryStream(temp));
var secTokenScript = doc.DocumentNode.Descendants()
.Where(e =>
String.Compare(e.Name, "script", true) == 0 &&
String.Compare(e.ParentNode.Name, "div", true) == 0 &&
e.InnerText.Length > 0 &&
e.InnerText.Trim().StartsWith("var region")
).FirstOrDefault().InnerText;
var securityToken = secTokenScript;
securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push"));
securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", "");
var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var scriptDates = dates.Select(x => new ScriptDate { DateString = x });
foreach (var date in scriptDates)
{
DatesAndTimes.Add(date.DateString);
}
}
catch(WebException wex)
{
if (wex.Response != null)
{
using (var errorResponse = (HttpWebResponse)wex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
}
}
}
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
this.Init();
}
}
When I use a breakpoint on the line:
string error = reader.ReadToEnd();
I see html content and in the content I see the text:
error occurred while processing your request. Return to the homepage of Sat24.com
What I want to do is somehow when the exception happen to start over again and try the download try the method ExtractDateAndTime.
I think using a timer some how and count back showing the user something like 30 seconds and try again. Will 30 seconds try will be consider as spam/flooding in the server site ?
This is the full class code but the exception is on this method ExtractDateAndTime.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using System.Xml;
using HtmlAgilityPack;
using System.ComponentModel;
namespace SatelliteImages
{
class ExtractImages
{
static WebClient client;
static string htmltoextract;
public static List<string> countriescodes = new List<string>();
public static List<string> countriesnames = new List<string>();
public static List<string> DatesAndTimes = new List<string>();
public static List<string> imagesUrls = new List<string>();
static string firstUrlPart = "http://www.sat24.com/image2.ashx?region=";
static string secondUrlPart = "&time=";
static string thirdUrlPart = "&ir=";
public class ProgressEventArgs : EventArgs
{
public int Percentage { get; set; }
public string StateText { get; set; }
}
public event EventHandler<ProgressEventArgs> ProgressChanged;
public void Init()
{
object obj = null;
int index = 0;
ExtractCountires();
foreach (string cc in countriescodes)
{
// raise event here
ProgressChanged?.Invoke(obj,new ProgressEventArgs{ Percentage = 100 * index / countriescodes.Count, StateText = cc });
ExtractDateAndTime("http://www.sat24.com/image2.ashx?region=" + cc);
index +=1;
}
ImagesLinks();
}
public void ExtractCountires()
{
try
{
htmltoextract = "http://sat24.com/en/?ir=true";//"http://sat24.com/en/";// + regions;
client = new WebClient();
client.DownloadFile(htmltoextract, #"c:\temp\sat24.html");
client.Dispose();
string tag1 = "<li><a href=\"/en/";
string tag2 = "</a></li>";
string s = System.IO.File.ReadAllText(#"c:\temp\sat24.html");
s = s.Substring(s.IndexOf(tag1));
s = s.Substring(0, s.LastIndexOf(tag2) + tag2.ToCharArray().Length);
s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
string[] parts = s.Split(new string[] { tag1, tag2 }, StringSplitOptions.RemoveEmptyEntries);
string tag3 = "<li><ahref=\"/en/";
for (int i = 0; i < parts.Length; i++)
{
if (i == 17)
{
//break;
}
string l = "";
if (parts[i].Contains(tag3))
l = parts[i].Replace(tag3, "");
string z1 = l.Substring(0, l.IndexOf('"'));
if (z1.Contains("</ul></li><liclass="))
{
z1 = z1.Replace("</ul></li><liclass=", "af");
}
countriescodes.Add(z1);
countriescodes.GroupBy(n => n).Any(c => c.Count() > 1);
string z2 = parts[i].Substring(parts[i].LastIndexOf('>') + 1);
if (z2.Contains("&"))
{
z2 = z2.Replace("&", " & ");
}
countriesnames.Add(z2);
countriesnames.GroupBy(n => n).Any(c => c.Count() > 1);
}
}
catch (Exception e)
{
if (countriescodes.Count == 0)
{
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
Init();
}
}
}
public void ExtractDateAndTime(string baseAddress)
{
try
{
var wc = new WebClient();
wc.BaseAddress = baseAddress;
HtmlDocument doc = new HtmlDocument();
var temp = wc.DownloadData("/en");
doc.Load(new MemoryStream(temp));
var secTokenScript = doc.DocumentNode.Descendants()
.Where(e =>
String.Compare(e.Name, "script", true) == 0 &&
String.Compare(e.ParentNode.Name, "div", true) == 0 &&
e.InnerText.Length > 0 &&
e.InnerText.Trim().StartsWith("var region")
).FirstOrDefault().InnerText;
var securityToken = secTokenScript;
securityToken = securityToken.Substring(0, securityToken.IndexOf("arrayImageTimes.push"));
securityToken = secTokenScript.Substring(securityToken.Length).Replace("arrayImageTimes.push('", "").Replace("')", "");
var dates = securityToken.Trim().Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
var scriptDates = dates.Select(x => new ScriptDate { DateString = x });
foreach (var date in scriptDates)
{
DatesAndTimes.Add(date.DateString);
}
}
catch(WebException wex)
{
if (wex.Response != null)
{
using (var errorResponse = (HttpWebResponse)wex.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
string error = reader.ReadToEnd();
}
}
}
countriescodes = new List<string>();
countriesnames = new List<string>();
DatesAndTimes = new List<string>();
imagesUrls = new List<string>();
this.Init();
}
}
public class ScriptDate
{
public string DateString { get; set; }
public int Year
{
get
{
return Convert.ToInt32(this.DateString.Substring(0, 4));
}
}
public int Month
{
get
{
return Convert.ToInt32(this.DateString.Substring(4, 2));
}
}
public int Day
{
get
{
return Convert.ToInt32(this.DateString.Substring(6, 2));
}
}
public int Hours
{
get
{
return Convert.ToInt32(this.DateString.Substring(8, 2));
}
}
public int Minutes
{
get
{
return Convert.ToInt32(this.DateString.Substring(10, 2));
}
}
}
public void ImagesLinks()
{
int cnt = 0;
foreach (string countryCode in countriescodes)
{
cnt++;
for (; cnt < DatesAndTimes.Count(); cnt++)
{
string imageUrl = firstUrlPart + countryCode + secondUrlPart + DatesAndTimes[cnt] + thirdUrlPart + "true";
imagesUrls.Add(imageUrl);
if (cnt % 10 == 0) break;
}
}
}
}
}
What i want is in case of the exception happen to start over clean over again the whole class operation.
In Form1 i start the class operation first time once:
In top:
ExtractImages ei = new ExtractImages();
Then in constructor:
ei.Init();
The problem is this exception that sometimes happen.
You could go with something like Polly or the Transient Fault Handling Application Block to apply a retry strategy to your code.
Both packages provide multiple out-of-the-box components for various scenarios and you can always develop you own. Some of the included retry policies:
Incremental
Fixed interval
Exponential back-off
Retry
Retry for ever
Retry and wait
Wait and retry for ever
...
I want to pass real time signals from emotive to octave.
I tried to write a c# wrapper for octave. Here is the code.
namespace LibSharpTave {
public class Octave {
Process OctaveProcess { get; set; }
private string OctaveEchoString { get; set; }
public Octave(string PathToOctaveBinaries) {
StartOctave(PathToOctaveBinaries, false);
}
public Octave(string PathToOctaveBinaries, bool CreateWindow) {
StartOctave(PathToOctaveBinaries, CreateWindow);
}
string ptob;
bool cw;
private void StartOctave(string PathToOctaveBinaries, bool CreateWindow) {
ptob = PathToOctaveBinaries;
cw = CreateWindow;
this.OctaveEchoString = Guid.NewGuid().ToString();
OctaveProcess = new Process();
ProcessStartInfo pi = new ProcessStartInfo();
if (PathToOctaveBinaries[PathToOctaveBinaries.Length - 1] != '\\')
PathToOctaveBinaries = PathToOctaveBinaries + "\\";
pi.FileName = PathToOctaveBinaries + "octave.exe";
pi.RedirectStandardInput = true;
pi.RedirectStandardOutput = true;
pi.RedirectStandardError = true;
pi.UseShellExecute = false;
pi.CreateNoWindow = !CreateWindow;
pi.Verb = "open";
//
pi.WorkingDirectory = ".";
OctaveProcess.StartInfo = pi;
OctaveProcess.Start();
OctaveProcess.OutputDataReceived += new DataReceivedEventHandler(OctaveProcess_OutputDataReceived);
OctaveProcess.BeginOutputReadLine();
OctaveEntryText = ExecuteCommand(null);
//OctaveProcess.OutputDataReceived += new DataReceivedEventHandler(Oc
}
public double GetScalar(string scalar) {
string rasp = ExecuteCommand(scalar, 30000);
string val = rasp.Substring(rasp.LastIndexOf("\\") + 1).Trim();
return double.Parse(val);
}
public double[] GetVector(string vector) {
string rasp = ExecuteCommand(vector, 30000);
string[] lines = rasp.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
int i = 0;
//catam urmatorul entry
List<double> data = new List<double>();
while (i != lines.Length) {
string line = lines[i];
if (line.Contains("through") || line.Contains("and")) {
i++;
line = lines[i];
string[] dataS = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
for (int k = 0; k < dataS.Length; k++) {
data.Add(double.Parse(dataS[k]));
}
}
i++;
}
//caz special in care a pus toate rezultatele pe o singura linie
if (data.Count == 0) {
string[] dataS = lines[lines.Length - 1].Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (dataS.Length != 0)
for (int k = 0; k < dataS.Length; k++) {
data.Add(double.Parse(dataS[k]));
}
}
return data.ToArray();
}
public double[][] GetMatrix(string matrix) {
//string rasp = ExecuteCommand(matrix);
//aflam numarul de randuri
string rasp = ExecuteCommand(matrix + "(:,1)", 30000);
string[] lines = rasp.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
double[][] mat = new double[lines.Length - 1][];
for (int i = 0; i < mat.Length; i++) {
mat[i] = GetVector(matrix + "(" + (i + 1) + ",:)");
}
return mat;
}
StringBuilder SharedBuilder = new StringBuilder();
ManualResetEvent OctaveDoneEvent = new ManualResetEvent(false);
public string OctaveEntryText { get; internal set; }
public void WorkThread(object o) {
string command = (string)o;
SharedBuilder.Clear();
OctaveDoneEvent.Reset();
if (command != null) {
OctaveProcess.StandardInput.WriteLine(command);
}
//ca sa avem referinta pentru output
OctaveProcess.StandardInput.WriteLine("\"" + OctaveEchoString + "\"");
OctaveDoneEvent.WaitOne();
}
public string ExecuteCommand(string command, int timeout) {
if (OctaveProcess.HasExited) {
StartOctave(ptob, cw);
if (OctaveRestarted != null) OctaveRestarted(this, EventArgs.Empty);
}
exitError = false;
Thread tmp = new Thread(new ParameterizedThreadStart(WorkThread));
tmp.Start(command);
if (!tmp.Join(timeout)) {
tmp.Abort();
throw new Exception("Octave timeout");
}
if (exitError) {
throw new Exception(errorMessage);
}
return SharedBuilder.ToString();
}
public string ExecuteCommand(string command) {
// Thread tmp = new Thread(new ParameterizedThreadStart(WorkThread));
// tmp.Start(command);
// tmp.Join();
// return SharedBuilder.ToString();
if (OctaveProcess.HasExited)
{
OctaveProcess.Start();
}
SharedBuilder.Clear();
if (command != null)
{
OctaveProcess.StandardInput.WriteLine(command);
OctaveDoneEvent.Reset();
OctaveDoneEvent.WaitOne();
return SharedBuilder.ToString();
}
Octave octave = new Octave(#"c:\software\Octave-3.6.4",false);
octave.ExecuteCommand("a=[1,2;3,4];");
octave.ExecuteCommand("result=a;");
double[][] m = octave.GetMatrix("result");
}
bool exitError = false;
string errorMessage = null;
void OctaveProcess_OutputDataReceived(object sender, DataReceivedEventArgs e) {
if (e.Data == null) {
SharedBuilder.Clear();
//errorMessage = OctaveProcess.StandardError.ReadToEnd();
SharedBuilder.Append("Octave has exited with the following error message: \r\n" + errorMessage);
//exitError = true;
OctaveDoneEvent.Set();
return;
}
if (e.Data.Trim() == "ans = " + OctaveEchoString)
OctaveDoneEvent.Set();
else
SharedBuilder.Append(e.Data + "\r\n");
}
public event OctaveRestartedEventHandler OctaveRestarted;
public delegate void OctaveRestartedEventHandler(object sender, EventArgs e);
}
//custom class
// void OctaveProcess_OutputDataReceived (object sender, DataReceivedeEventArgs e)
/*{
if (e.data == null)
{
SharedBuilder.Clear();
SharedBuilder.Append("Octave has exited with the following error message: \r\n" + OctaveProcess.StandardError.ReadToEnd());
OctaveDoneEvent.Set();
return;
}
if (e.data.Trim == "ans =" + OctaveEchoString())
OctaveDoneEvent.set();
else
SharedBuilder.Append(e.Data + "\r\n");
}*/
}
And it is returning the error: "Not all code paths return a value".
How can I fix this error?
Your ExecuteCommand function should return a string, but doesn't. This is the ExecuteCommand overload that accepts one argument.
This function has string as return type but does not return anything when if (command != null) statement is false -
public string ExecuteCommand(string command) {
// Thread tmp = new Thread(new ParameterizedThreadStart(WorkThread));
// tmp.Start(command);
// tmp.Join();
// return SharedBuilder.ToString();
if (OctaveProcess.HasExited)
{
OctaveProcess.Start();
}
SharedBuilder.Clear();
if (command != null)
{
OctaveProcess.StandardInput.WriteLine(command);
OctaveDoneEvent.Reset();
OctaveDoneEvent.WaitOne();
return SharedBuilder.ToString();
}
Octave octave = new Octave(#"c:\software\Octave-3.6.4",false);
octave.ExecuteCommand("a=[1,2;3,4];");
octave.ExecuteCommand("result=a;");
double[][] m = octave.GetMatrix("result");
//**** The Error is here *****
//return a string here
}
Return a string at the mention section. I highlighted in the comment as - //**** The Error is here *****
Your
public string ExecuteCommand(string command) {
has no return statement even though you specified return type string.
Either return some string or make its return type void as in :
public void ExecuteCommand(string command) {