I am able to read my text file however when I go and click my edit button it moves all the current rows in the text file to the top row and doesn't update anything. Also how would I go about adding a row to the text file without moving the rows?
private void btnEdit_Click(object sender, EventArgs e)
{
BugTrackers cs = Bugs[index];
// DisplayBugs();
// Update datafile
UpdateBugsInfo();
}
private void UpdateBugsInfo()
{
if (lstBugs.SelectedIndex > -1)
{
System.IO.StreamWriter sw = new System.IO.StreamWriter("smBugs.txt", false);
for (int i = 0; i <= Bugs.Count - 1; i++)
{
sw.Write(Bugs[i].BugsName);
sw.Write(",");
sw.Write(Bugs[i].BugsDesc);
}
sw.Close();
}
}
The StreamWriter object you are creating is having wrong parameter value for append. You need to set that as true OR just remove that parameter since it’s default value is true.
System.IO.StreamWriter sw = new System.IO.StreamWriter("smBugs.txt", true);
OR
System.IO.StreamWriter sw = new System.IO.StreamWriter("smBugs.txt");
Here is the link from Microsoft.
https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.-ctor?view=netframework-4.7.2#System_IO_StreamWriter__ctor_System_String_System_Boolean_
You are also not using the using statement, which ensures the StreamWriter object is removed from memory when no longer needed. Please go through this article to understand it better.
https://www.dotnetperls.com/streamwriter
Hope this helps!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace BugTracker
{
struct BugTrackers
{
public string BugsName;
public string BugsDesc;
}
public partial class YoungKidsBugTracker : Form
{
// Field to hold a list of BugTrackers objects
private List<BugTrackers> Bugs = new List<BugTrackers>();
private int index; // index fo selected bugs in combobox
public YoungKidsBugTracker()
{
InitializeComponent();
}
private void ReadFile()
{
try
{
//Declare a varialble to hold Bugs Name
StreamReader inputFile; // To Read the file
string line; // To hold a line from the file
// Create an instance of the Bug Accounts
BugTrackers entry = new BugTrackers();
// Create a delimeter array
char[] delim = { ',' };
// Open the file and get a StreamReader Object
inputFile = File.OpenText("smBugs.txt");
// Read the file's contents
while (!inputFile.EndOfStream)
{
// Read a line from the file
line = inputFile.ReadLine();
// Tokenize the line
string[] tokens = line.Split(delim);
// Stores the tokens in the entry object
entry.BugsName = tokens[0];
entry.BugsDesc = tokens[1];
// Add the entry object to the combobox
Bugs.Add(entry);
}
// Close the File
inputFile.Close();
}
catch (Exception ex)
{
// Display an error message
MessageBox.Show(ex.Message);
}
}
private void lstBugs_SelectedIndexChanged(object sender, EventArgs e)
{
// Get the index of the sselected item
index = lstBugs.SelectedIndex;
// Display Bug Information
DisplayBugs();
}
private void DisplayBugs()
{
//Show Data
txtBugsName.Text = Bugs[index].BugsName;
rtxtBugDesc.Text = Bugs[index].BugsDesc.ToString();
}
private void YoungKidsBugTracker_Load(object sender, EventArgs e)
{
// Read the Bugs.txt file
ReadFile();
// Display Bug Information
BugNameDisplay();
}
private void btnEdit_Click(object sender, EventArgs e)
{
BugTrackers cs = Bugs[index];
// DisplayBugs();
// Update datafile
UpdateBugsInfo();
}
private void UpdateBugsInfo()
{
if (lstBugs.SelectedIndex > -1)
{
System.IO.StreamWriter sw = new System.IO.StreamWriter("smBugs.txt");
for (int i = 0; i <= Bugs.Count - 1; i++)
{
sw.Write(Bugs[i].BugsName);
sw.Write(",");
sw.WriteLine(Bugs[i].BugsDesc);
// sw.Write(Environment.NewLine);
}
sw.Close();
}
}
private void BugNameDisplay()
{
// Display the list of Bug Names in the List Control
foreach (BugTrackers entry in Bugs)
{
lstBugs.Items.Add(entry.BugsName );
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
}
}
}
This is the code in its entirety. I have a list box with 2 text boxes to hold the bug name and description. I have 3 buttons Add, Edit and Delete. If an item is selected from the listbox it will display the bugname and description. If the entry needs updated changes are made and will change the information needed. If a new bug is added you would use the add button same for the delete button.
Related
I am getting an error that my textfile that is used to create and save my dictionary is being used by another process, I have used Process explorer to no result on what could be using my file. Below is my code and the code throwing this error.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace meade_9_10
{
public partial class Form1 : Form
{
private Dictionary<string, string> names = new Dictionary<string, string>()
{
};
public Form1()
{
//Make sure Form1 is loaded and ran on program open
InitializeComponent();
this.Load += Form1_Load;
}
private void Form1_Load(object sender, EventArgs e)
{
//Grab myfile.txt and convert to array
StreamReader sr = new StreamReader("myfile.txt");
string line;
while ((line = sr.ReadLine()) != null)
{
string[] arr = line.Split(',');
int i = 0;
//Add array objects to names dictionary
while (i < arr.Length)
{
names[arr[i]] = arr[i + 1];
i += 2;
}
}
}
private void btnAdd_Click(object sender, EventArgs e)
{
//declare variables
string nameAdd;
string emailAdd;
//Put user input into variable
nameAdd = txtNameAdd.Text;
emailAdd = txtEmailAdd.Text;
//Declare new dictionary key pair as user input
names[emailAdd] = nameAdd;
//clear the textbox controls
txtNameAdd.Text = "";
txtEmailAdd.Text = "";
}
private void btnDelete_Click(object sender, EventArgs e)
{
string emailDel;
emailDel = txtEmailDel.Text;
//Remove key pair that is inputted by user
names.Remove(emailDel);
}
private void btnChange_Click(object sender, EventArgs e)
{
//Declare variables
string emailDel;
string nameAdd;
string emailAdd;
//Assign values to variables
emailDel = txtEmailChange.Text;
nameAdd = txtNameNew.Text;
emailAdd = txtEmailNew.Text;
//Delete the user inputted email to change
names.Remove(emailDel);
//Add the new key pair values to dictionary
names.Add(emailAdd, nameAdd);
}
private void btnLookUp_Click(object sender, EventArgs e)
{
//Declare variable
string email = txtEmail.Text;
//If statement to check if dictionary contains key value
if (names.ContainsKey(email))
{
outputName.Text = names[email];
outputEmail.Text = email;
}
}
private void btnExit_Click(object sender, EventArgs e)
{
//writes the names dictioanry to array inside text file
File.WriteAllLines("myfile.txt",
names.Select(x => x.Key + "," + x.Value ).ToArray());
//Closes the program
this.Close();
}
}
}
The part of my code giving me the error
System.IO.IOException: 'The process cannot access the file 'C:\Users\Adrian\Desktop\ALL SCHOOL FILES\Fall 2021\C#\meade_9_10\bin\Debug\myfile.txt' because it is being used by another process.'
is
names.Select(x => x.Key + "," + x.Value ).ToArray());
I just cannot figure out what process is using my text file that is breaking this program, it was working earlier and I haven't made any changes except for removing redundant white space between functions.
Try using the
StreamReader.Close() method after your innermost while loop:
Closes the StreamReader object and the underlying stream, and releases any system resources associated with the reader.
Alternatively, you can use the using statement:
Provides a convenient syntax that ensures the correct use of IDisposable objects.
I am to create a program that reads from an outputfile AND also add FURTHER text to that output file trough "AppendText" method so that nothing in the text file is overriden. You can add things to the listbox via a textbox, but what I am trying to do is to prevent duplicate entries. I have implmeneted a code that does supposedly prevents multiple entries, but it doesn't work properly. It gives a message that I set "Duplicate entry" but it still adds the entry. ANY WAY TO FIX THIS? Please Help THANKS.
This is the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace BIT_UNITS
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void displayButton_Click(object sender, EventArgs e)
{
try
{
//Variables
string unitsList;
//declare streamReader variable
StreamReader inputFile;
//Open file & get units list
inputFile = File.OpenText("BITS_Units.txt");
//Clear anything currently in the listbox
unitsListBox.Items.Clear();
//Read the file's Contents
while (!inputFile.EndOfStream)
{
//Get Units List
unitsList = inputFile.ReadLine();
//Display the units list in the listbox
unitsListBox.Items.Add(unitsList);
}
//close the file
inputFile.Close();
}
catch
{
MessageBox.Show("Error");
}
}
private void addUnitButton_Click(object sender, EventArgs e)
{
try
{
//Declare streamwriter variable
StreamWriter outputFile;
//Open file and get a streamwriter object
outputFile = File.AppendText("BITS_Units.txt");
//Record inputs to the file
outputFile.WriteLine(addUnitsTextBox.Text);
//Close the file
outputFile.Close();
//Determine wether textbox is filled
if (addUnitsTextBox.Text== Text)
{
//Display message
MessageBox.Show("Unit was successfully added.");
}
//Determine wether textbox is filled
if (addUnitsTextBox.Text == "")
{
MessageBox.Show("Please enter a unit name to add to the list.");
}
if (unitsListBox.Items.Contains(addUnitsTextBox.Text))
{
MessageBox.Show("This unit already exists");
}
else
{
unitsListBox.Items.Add(addUnitsTextBox.Text);
addUnitsTextBox.Text = "";
}
}
catch (Exception)
{
MessageBox.Show("error");
}
}
private void clearButton_Click(object sender, EventArgs e)
{
try
{
//Clear data
addUnitsTextBox.Text = "";
unitsListBox.Items.Clear();
}
catch (Exception)
{
MessageBox.Show("Error");
}
}
private void exitButton_Click(object sender, EventArgs e)
{
//Close the form
this.Close();
}
}
}
Before adding item to list box, check if doesn't exist in the list box.
if (!unitsListBox.Items.Contains(unitsList) )
{
unitsListBox.Items.Add(unitsList);
}
This question already has answers here:
When is a C# value/object copied and when is its reference copied?
(3 answers)
Closed 8 years ago.
I am working on a Microsoft Visual C# Form Application that is to be used to create all the data that would go into RPG game. I have designed a structure and encased it all into a class so I can easily read and write to/from an XML file.
On my main form I have a "public static"/"Global" variable that all of my sub forms can copy information from... manipulate what it needs to... and send that information back to it.
For example. I want multiple types of currencies. The form that deals with currencies copies only the currency data from the global variable and has free reign to manipulate only THAT copy. Only when the user clicks the "Apply" or "Accept" button should the global variable be updated to reflect those changes. If the "Cancel" button is clicked it should just close the form and the copied data should get tossed to the winds when the form is disposed.
Unfortunately this is not the case. Whenever I change the data of the copy its changes seem to reflect on the global variable as well. Is there a concept here I am missing here and don't understand. Somebody please explain. I've checked over my code and there are only those two points where the data should be updated.
Code from "Main" Form
public partial class frmMain : Form
{
public static RPGDataCollection DATA = new RPGDataCollection();
public static string FILE = "";
public frmMain ()
{
InitializeComponent();
FillDefaultData();
}
/// <summary>
/// Sets item info status text.
/// </summary>
/// <param name="text">Text to be displayed.</param>
private void SetItemInfo (string text)
{
lblItemInfo.Text = text;
}
Currency Form Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RPGData.ObjectTypes.DataGroups;
namespace RPGData.EntryForms
{
public partial class frmCurrencies : Form
{
#region Fields
private List<Currency> datCurrencies = new List<Currency>();
private string strEntry = "";
private bool blnGSC = false;
private bool blnUpperFlag = false;
private int intIndex = 0;
#endregion
#region Constructor
public frmCurrencies ()
{
InitializeComponent();
}
#endregion
#region Events
private void frmCurrencies_Load (object sender, EventArgs e)
{
datCurrencies = frmMain.DATA.Currencies;
DisplayData();
}
private void btnReplace_Click (object sender, EventArgs e)
{
intIndex = lstCurrencies.SelectedIndex;
Currency c = datCurrencies[intIndex];
if (txtEntry.Text.Trim().Length > 0)
{
SetValues();
c.Name = strEntry;
c.HandlesGSC = blnGSC;
c.Amount = 0;
datCurrencies[intIndex] = c;
}
ResetFields();
DisplayData();
}
private void btnCancel_Click (object sender, EventArgs e)
{
this.Close();
}
private void btnAdd_Click (object sender, EventArgs e)
{
if (txtEntry.Text.Trim().Length > 0)
{
SetValues();
Currency c = new Currency();
c.Name = strEntry;
c.HandlesGSC = blnGSC;
c.Amount = 0;
datCurrencies.Add(c);
}
ResetFields();
DisplayData();
}
private void btnRemove_Click (object sender, EventArgs e)
{
intIndex = lstCurrencies.SelectedIndex;
if (intIndex >= 0)
datCurrencies.RemoveAt(intIndex);
ResetFields();
DisplayData();
}
private void btnApply_Click (object sender, EventArgs e)
{
frmMain.DATA.Currencies = datCurrencies;
}
private void btnAccept_Click (object sender, EventArgs e)
{
frmMain.DATA.Currencies = datCurrencies;
this.Close();
}
private void lstCurrencies_SelectedIndexChanged (object sender, EventArgs e)
{
intIndex = lstCurrencies.SelectedIndex;
Currency c = datCurrencies[intIndex];
txtEntry.Text = c.Name;
chkGSC.Checked = c.HandlesGSC;
}
#endregion
#region Methods
private void DisplayData ()
{
lstCurrencies.Items.Clear();
for (int i = 0; i < datCurrencies.Count; i++)
{
string gsc = "";
if (datCurrencies[i].HandlesGSC)
gsc = "*";
else
gsc = " ";
lstCurrencies.Items.Add("[ " + gsc + " ] " + datCurrencies[i].Name);
}
}
private void ResetFields ()
{
strEntry = "";
blnGSC = false;
txtEntry.Text = strEntry;
chkGSC.Checked = blnGSC;
txtEntry.Focus();
}
private void SetValues ()
{
string entry = ToAllUpper(txtEntry.Text);
strEntry = entry;
blnGSC = chkGSC.Checked;
}
private string ToAllUpper (string str)
{
string entry = "";
for (int i = 0; i < str.Length; i++)
{
string c = "";
if (i == 0)
c = str.Substring(0, 1).ToUpper();
else if (str.Substring(i, 1) == " ")
{
c = " ";
blnUpperFlag = true;
}
else if (blnUpperFlag)
{
c = str.Substring(i, 1).ToUpper();
blnUpperFlag = false;
}
else
c = str.Substring(i, 1);
entry += c;
}
return entry;
}
#endregion
}
}
Any help you can toss me and help me understand what might be happening would be great (or you see a bug or mistake I don't).
Thanks!
This line of code datCurrencies = frmMain.DATA.Currencies is actually creates another one reference to frmMain.DATA.Currencies and doesn't deep copying it.
So all changes you made - is actually made on original object.
You have to clone it (create deep copy), not just create additional reference.
For example, if your Currency is struct (value-type), following will be sufficient:
datCurrencies = new List<Currency>(frmMain.DATA.Currencies);
But if your Currency is class - you may consider following approach:
create Clone method in your Currency class that will return clone of current object and then populate your datCurrencies like:
datCurrencies = new List<Currency>(frmMain.DATA.Currencies.Count);
foreach(var currency in frmMain.DATA.Currencies)
datCurrencies.Add(currency.Clone());
You copy the reference to a list here:
datCurrencies = frmMain.DATA.Currencies;
Afetr this asignment there is still just one list and datCurrencies points to this one global list.
Instead you need to create a deep copy i.e copy the contents from your global list to your local list.
I have this Code in Form1. Im doing a search for xml files. When i find them im using listBox1 selected index changed event and i want to do that when i select item in the lixtBox it will consider it as a file will parse it content and show me the parsed content.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;
using System.IO;
using System.Collections;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
DirectoryInfo dirinf = new DirectoryInfo(#"C:\");
List<FileSystemInfo> fsi = new List<FileSystemInfo>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
button1.Enabled = false;
}
private void ParseAndDisplayXml(string filename)
{
XDocument document = XDocument.Load(filename);
var list = document.Root.Elements("Message")
.Select(
e => new
{
Date = e.Attribute("Date").Value.ToString(),
Time = e.Attribute("Time").Value.ToString(),
Text = e.Element("Text").Value.ToString()
}
);
string result="";
foreach (var item in list)
{
result += string.Format("Date--{0},Time--{1},Text--{2}", item.Date, item.Time, item.Text + Environment.NewLine);
}
}
public void Search(string strExtension,
DirectoryInfo di,
List<FileSystemInfo> pResult)
{
try
{
foreach (FileInfo fi in di.GetFiles())
{
if (InvokeRequired)
{
BeginInvoke(new Action(() => label2.Text = fi.Name));
}
if (fi.Name == "MessageLog.xsl")
{
foreach (FileInfo fii in di.GetFiles())
{
if (fii.Extension == strExtension)
pResult.Add(fii);
}
if (InvokeRequired)
{
BeginInvoke(new Action(() => label4.Text = pResult.Count.ToString() + Environment.NewLine));
}
}
}
foreach (DirectoryInfo diChild in di.GetDirectories())
Search(strExtension, diChild, pResult);
}
catch (Exception e)
{
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Search(".xml", dirinf, fsi);
backgroundWorker1.ReportProgress(100);
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
for (int i = 0; i < fsi.Count; i++)
{
listBox1.Items.Add(fsi[i].Name + Environment.NewLine);
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label2.Text = listBox1.SelectedItem.ToString();
}
}
}
Im starting the search from C:\
Then when the search so over completed im adding the items it found to the listBox1.
For example now in my listBox1 i have 4 files:
danny.xml
adi.xml
sharon.xml
yoval.xml
In the selectedindexchanged i added option so the user can move between the items.
Now what i want to do is when the user select some index for example index [1] in the listBox and only if he clicked enter with the keyboard or clicked with the mouse left click it will call/use the function: ParseAndDisplayXML.
Then it will parse the selected index wich need to be translated to a file so in the backgroundWorker1_RunWorkerCompleted event i madding the files to the listBox as items but only with the names of the files. If i did .FullName instead .Name it was adding the files names with the directories too.
So i need somehow to get the FullName of the files in the completed event i think then when selecting one of the FullName items to parse it and display it in the listBox.
The parse function should take the specific content from the xml files and it worked i checked this function before alone.
The problem is how do i make that the user will select the index by click/key enter and how to parse and display it ?
When you add something to a listbox.
It expects an object, and sets the text to object.ToString()
e.g.
MyListBox.Add(100);
Would box 100 and display "100"
Couldn't find if FileSystemInfo's ToString() method has been overridden but first thing to try would be
private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
// newline is unnecesary and you should be using foreach
foreach(FileSystemInfo f in fsi)
{
listBox1.Items.Add(f);
}
}
// display full name of file
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label2.Text = ((FileSystemInfo)listBox1.SelectedItem).Fullname;
}
If FileSystemInfo.ToString() doesn't return Name, there are a few ways to deal with that.
If you don't want to hold on to the FileSystemInfo instances, we can deal with that too.
I want to make a RSS reader which makes it possible to get multiple news feeds at the same time, without my application "freezing" while getting the feed. To do this, I want some of the code to run in a seperate thread. I have tried some different things, to make it run in a seperate thread, but I keep getting exceptions. My code looks like this atm:
namespace NewsReader
{
public partial class Form1 : Form
{
XmlTextReader rssReader;
XmlDocument rssDoc;
XmlNode nodeRss;
XmlNode nodeChannel;
XmlNode nodeItem;
ListViewItem rowNews;
public Form1()
{
InitializeComponent();
}
private void btnRead_Click(object sender, EventArgs e)
{
//Creates a XmlTextReader which reads from the url entered in input field
rssReader = new XmlTextReader(txtUrl.Text);
//Creates an xml doc to save the content of the entered path
rssDoc = new XmlDocument();
//Loads the xml content from the reader into a XmlDocument
rssDoc.Load(rssReader);
//Make a loop to search for the <rss> tag
for (int i = 0; i < rssDoc.ChildNodes.Count; i++)
{
//If the childenode is the rss tag
if (rssDoc.ChildNodes[i].Name == "rss")
{
//the <rss> tag is found, and we know where it is
nodeRss = rssDoc.ChildNodes[i];
}
}
//Make a loop to search for the <channel> tag
for (int i = 0; i < nodeRss.ChildNodes.Count; i++)
{
//If the childnode is the channel tag
if (nodeRss.ChildNodes[i].Name == "channel")
{
//The channel tag is found and we know where it is
nodeChannel = nodeRss.ChildNodes[i];
}
}
//Make a loop to search for the <item> tag
for (int i = 0; i < nodeChannel.ChildNodes.Count; i++)
{
//If the childnode is the item tag
if (nodeChannel.ChildNodes[i].Name == "item")
{
//the item tag is found, and we know where it is
nodeItem = nodeChannel.ChildNodes[i];
//Creates a new row in the LstView which contains information from inside the nodes
rowNews = new ListViewItem();
rowNews.Text = nodeItem["title"].InnerText;
rowNews.SubItems.Add(nodeItem["link"].InnerText);
lstView.Items.Add(rowNews);
}
}
}
}
}
Does anyone have some examples of how to handle this problem? Code examples with my code is very appreciated :)
Thanks in advance.
You may checkout the BackgroundWorker class. And here's an example:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.XPath;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync(txtUrl.Text);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var rssDoc = XDocument.Load((string)e.Argument);
var items = new List<ListViewItem>();
foreach (var item in rssDoc.XPathSelectElements("//item"))
{
var listItem = new ListViewItem();
listItem.Text = item.Element("title").Value;
listItem.SubItems.Add(item.Element("link").Value);
items.Add(listItem);
}
e.Result = items.ToArray();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lstView.Items.AddRange((ListViewItem[])e.Result);
}
}
If you're using .NET 3.5 or later you can use the SyndicationFeed type to make parsing the RSS feed easier.
I'm adapting Darin Dimitrov's code example here:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.ServiceModel.Syndication;
using System.Xml.Linq;
using System.Xml.XPath;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync(txtUrl.Text);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var reader = new XmlTextReader((string)e.Argument);
var feed = SyndicationFeed.Load(reader);
var items = new List<ListViewItem>();
foreach (var item in feed.Items)
{
var listItem = new ListViewItem();
listItem.Text = item.Title;
foreach (var link in item.Links)
{
listItem.SubItems.Add(link.Uri.AbsoluteUri);
}
items.Add(listItem);
}
e.Result = items.ToArray();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
lstView.Items.AddRange((ListViewItem[])e.Result);
}
}
If you are using .net 4.0 you can use the Task system for an even easier approach, and possibly better performance.
foreach (var item in rssDoc.XPathSelectElements("//item"))
{
Task fetch = new Task(() =>
{
// Go to server and get data....
// Add Data to UI...
});
fetch.Start();
}
The main benefit here is the Task system will decide how and when to run each fetch operation. In theory each operation will run in its own thread, so one or more at a time will be active instead of just one that you would see in a normal loop. The system is nice enough to do some load balancing for you too.