I have two exceptions here. Not sure why they occur because I use Form.Invoke to run UI updates on the UI thread. So first,
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Xml;
using System.Windows.Forms;
namespace Toplr
{
using System.Collections.Specialized;
using System.Xml.XPath;
using System.Xml.Linq;
using System.Text;
using System.ServiceModel.Web;
using System.ServiceModel.Syndication;
using System.Net;
using System.Web;
using System.Xml.Schema;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
public partial class ToplrForm : Form
{
private readonly Uri SearchBase = new Uri(@"http://www.twine.com/feed/atom/entries/");
private readonly UriTemplate SearchTemplate = new UriTemplate(@"search?type={type}&author={author}");
public ToplrForm()
{
InitializeComponent();
Exiting = false;
TaskContext = new TaskManager();
Items = new AsyncBindingList<Twine>(this);
twineBindingSource.DataSource = Items;
}
private void ToplrForm_Load(object sender, EventArgs e)
{
}
private readonly TaskManager TaskContext;
private readonly AsyncBindingList<Twine> Items;
private bool Exiting;
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Close()");
Close();
}
private void ToplrForm_FormClosing(object sender, FormClosingEventArgs e)
{
MessageBox.Show("Exiting = tru");
Exiting = true;
//TaskContext.Dispose();
}
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog()
{
ValidateNames = true
};
if (sfd.ShowDialog() == DialogResult.OK)
{
using (var xtw = new XmlTextWriter(sfd.FileName, Encoding.UTF8))
{
var xw = XmlWriter.Create(xtw);
xw.WriteStartDocument();
xw.WriteStartElement("opml");
xw.WriteAttributeString("version", "1.1");
xw.WriteStartElement("head");
xw.WriteElementString("title", userNameComboBox.Text);
xw.WriteEndElement();
xw.WriteStartElement("body");
foreach (var row in twineDataGridView.SelectedRows)
{
var twine = (Twine)((DataGridViewRow)row).DataBoundItem;
if (twine != null)
{
xw.WriteStartElement("outline");
xw.WriteAttributeString("text", twine.Title);
xw.WriteAttributeString("type", "link");
xw.WriteAttributeString("url", twine.HtmlAddress);
xw.WriteStartElement("outline");
xw.WriteAttributeString("text", twine.Title);
xw.WriteAttributeString("type", "atom");
xw.WriteAttributeString("url", twine.AtomAddress);
xw.WriteEndElement();
xw.WriteEndElement();
}
}
xw.WriteEndElement();
xw.WriteEndElement();
xw.WriteEndDocument();
xw.Close();
}
}
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Copyright (C) 2009 Bent Rasmussen");
}
private void accessButton_Click(object sender, EventArgs e)
{
var user = userNameComboBox.Text;
Task.Create(x => ProcessAccount(user));
}
public void ProcessAccount(string user)
{
this.Invoke((Action)(() =>
{
userNameComboBox.Enabled = false;
accessButton.Enabled = false;
toolStripStatusLabel1.Text = "Processing...";
}));
var param = new NameValueCollection();
param.Add("type", "Twine");
param.Add("author", user);
var source = SearchTemplate.BindByName(SearchBase, param);
var wc = new WebClient();
using (var feedStream = wc.OpenRead(source))
{
var reader = XmlReader.Create(feedStream);
var feed = SyndicationFeed.Load(reader);
int c = 0, i = 0;
foreach (var item in feed.Items)
{
this.Invoke((Action)(() =>
{
toolStripProgressBar1.Increment(1);
toolStripStatusLabel1.Text = "Processing...";
}));
if (item.Links.Count != 0)
{
//try
{
ProcessTwine(item);
i++;
}
//catch (Exception)
{
c++;
}
}
if (Exiting)
break;
}
}
this.Invoke((Action)(() =>
{
userNameComboBox.Enabled = true;
accessButton.Enabled = true;
}));
}
private Twine ProcessTwine(SyndicationItem item)
{
var result = new Twine();
result.Title = item.Title.Text;
result.HtmlAddress = item.Links[0].Uri.ToString();
result.AtomAddress = "";
var wc = new WebClient();
var data = wc.DownloadData(result.HtmlAddress);
var stream = new MemoryStream(data);
var readerSettings = new XmlReaderSettings()
{
ProhibitDtd = false,
ValidationType = ValidationType.None,
ValidationFlags = XmlSchemaValidationFlags.None,
};
var reader = XmlReader.Create(stream, readerSettings);
var doc = XDocument.Load(reader);
var htmlNs = (XNamespace)"http://www.w3.org/1999/xhtml";
var root = doc.Root;
var atom = from r in root.Descendants(htmlNs + "head").Descendants(htmlNs + "link")
where r.Attribute("rel").Value == "alternate" && r.Attribute("type").Value == "application/atom+xml"
select r.Attribute("href");
foreach (var e in atom)
{
if (e.Value != "")
{
result.AtomAddress = e.Value;
this.BeginInvoke((Action)(() =>
{
Items.Add(result);
toolStripProgressBar1.Increment(1);
}));
}
break;
}
return result;
}
}
}
This triggers the exception "Cannot access a disposed object" on this fragment
this.Invoke((Action)(() =>
{
toolStripProgressBar1.Increment(1);
toolStripStatusLabel1.Text = "Processing...";
}));
If this fragment is commented out, I run into the next problem - a TargetInvocationException on Program level.
The inner exception of this is an InvalidOperationException.
The code is quite simple, so it should not be hard to implement this, I just new a few hints to move on.