<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lesnikowski Blog &#187; WindowsForms</title>
	<atom:link href="http://www.lesnikowski.com/blog/tag/windowsforms/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lesnikowski.com/blog</link>
	<description>EMAIL IMAP POP3 SMTP FTP FTPS barcode components blog</description>
	<lastBuildDate>Sun, 05 Feb 2012 14:10:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Cross-thread operations with PostSharp</title>
		<link>http://www.lesnikowski.com/blog/cross-thread-operations-with-postsharp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cross-thread-operations-with-postsharp</link>
		<comments>http://www.lesnikowski.com/blog/cross-thread-operations-with-postsharp/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 15:00:43 +0000</pubDate>
		<dc:creator>Pawel Lesnikowski</dc:creator>
				<category><![CDATA[Presentation]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[PostSharp]]></category>
		<category><![CDATA[WindowsForms]]></category>

		<guid isPermaLink="false">http://www.lesnikowski.com/blog/?p=101</guid>
		<description><![CDATA[When you try to inform User Interface (UI) about the background operation progress or completion, you can not do it from the background thread. UI doesn&#8217;t like to be informed about anything from a different thread: you&#8217;ll get &#8220;System.InvalidOperationException: Cross-thread operation not valid: Control &#8216;xxx&#8217; accessed from a thread other than the thread it was [...]]]></description>
			<content:encoded><![CDATA[<p>When you try to <strong> inform User Interface</strong> (UI) about the <strong>background operation progress</strong> or <strong>completion</strong>, you can not do it from the background thread.</p>
<p>UI doesn&#8217;t like to be informed about anything from a different thread: you&#8217;ll get <strong>&#8220;System.InvalidOperationException: Cross-thread operation not valid: Control &#8216;xxx&#8217; accessed from a thread other than the thread it was created on.&#8221;</strong> exception from WinForms control, if you try:</p>
<pre class="brush: csharp;">
public void ShowStatus(ApplicationStatus status)
{
    this._lblServiceAddress.Text = &quot;Connected to: &quot;
        + status.WebServiceAddress;
    this._lblUserId.Text = &quot;Working as: &quot;
        + status.UserId;
}
</pre>
<p>The easiest sollution is to use <em>BeginInvoke </em>method on the control <em>Control</em> or <em>Form</em>:</p>
<pre class="brush: csharp;">
public void ShowStatus(ApplicationStatus status)
{
    this.BeginInvoke((MethodInvoker)(() =&gt;
        {
            this._lblServiceAddress.Text = &quot;Connected to: &quot;
                + status.WebServiceAddress;
            this._lblUserId.Text = &quot;Working as: &quot;
                + status.UserId;
        }));
}
</pre>
<p>Well, it&#8217;s fun to write this once, but if you have many operations done in background sooner or later you&#8217;d like to have something nicer. Like an <strong>attribute</strong> for example:</p>
<pre class="brush: csharp;">
[ThreadAccessibleUI]
public void ShowStatus(ApplicationStatus status)
{
    this._lblServiceAddress.Text = &quot;Connected to: &quot; + status.WebServiceAddress;
    this._lblUserId.Text = &quot;Working as: &quot; + status.UserId;
}
</pre>
<p>Here&#8217;s the attribute implementation of such attribute using PostSharp 1.5:</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// PostSharp attribute.
/// Use it to mark Control's methods that
/// are invoked from background thread.
/// &lt;/summary&gt;
/// &lt;remarks&gt;
/// Be careful as BeginInvoke uses the message queue.
/// This means that the interface will be refreshed
/// when application has a chance to process its messages.
/// &lt;/remarks&gt;
[AttributeUsage(AttributeTargets.Method)]
[Serializable] // required by PostSharp
public class ThreadAccessibleUIAttribute : OnMethodInvocationAspect
{
    public override void OnInvocation(
        MethodInvocationEventArgs eventArgs)
    {
        Control control = eventArgs.Instance as Control;
        if (control == null)
            throw new ApplicationException(
                &quot;ThreadAccessibleUIAttribute&quot; +
                &quot;can be applied only to methods on Control class&quot;);

        // The form may be closed before
        // this method is called from another thread.
        if (control.Created == false)
            return;

        control.BeginInvoke((MethodInvoker)eventArgs.Proceed);
    }
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.lesnikowski.com/blog/cross-thread-operations-with-postsharp/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

