<?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>Blog &#124; Limilabs &#187; WinForms</title>
	<atom:link href="http://www.limilabs.com/blog/tag/winforms/feed" rel="self" type="application/rss+xml" />
	<link>http://www.limilabs.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 21 May 2012 09:49:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Print barcode in WinForms video</title>
		<link>http://www.limilabs.com/blog/print-barcode-in-winforms-video?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=print-barcode-in-winforms-video</link>
		<comments>http://www.limilabs.com/blog/print-barcode-in-winforms-video#comments</comments>
		<pubDate>Wed, 01 Feb 2012 15:41:53 +0000</pubDate>
		<dc:creator>Limilabs support</dc:creator>
				<category><![CDATA[Component]]></category>
		<category><![CDATA[Barcode.dll]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[WinForms]]></category>

		<guid isPermaLink="false">http://www.limilabs.com/blog/?p=2439</guid>
		<description><![CDATA[In this video you&#8217;ll learn how to: Download and install Barcode.dll barcode component. Create new WinForms application that references Barcode.dll barcode component. Darg &#038; drop barcode windows control. Configure barcode windows control. Create print preview and print barcode. Enjoy]]></description>
			<content:encoded><![CDATA[<p>In this video you&#8217;ll learn how to:</p>
<ul>
<li>Download and install Barcode.dll <a href="http://www.limilabs.com/barcode">barcode component</a>.</li>
<li>Create new WinForms application that references Barcode.dll barcode component.</li>
<li>Darg &#038; drop barcode windows control.</li>
<li>Configure barcode windows control.</li>
<li>Create print preview and print barcode.</li>
</ul>
<p>Enjoy</p>
<p><object type="application/x-shockwave-flash" style="width:640px; height:505px;" data="http://www.youtube.com/v/C64Zqx1tv3A?rel=0&amp;showsearch=0&amp;version=3&amp;modestbranding=1"><param name="movie" value="http://www.youtube.com/v/I16OVFIKQzM?rel=0&amp;showsearch=0&amp;version=3&amp;modestbranding=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.limilabs.com/blog/print-barcode-in-winforms-video/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Create barcode in WinForms video</title>
		<link>http://www.limilabs.com/blog/create-barcode-in-winforms-video?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=create-barcode-in-winforms-video</link>
		<comments>http://www.limilabs.com/blog/create-barcode-in-winforms-video#comments</comments>
		<pubDate>Sun, 29 Jan 2012 15:41:51 +0000</pubDate>
		<dc:creator>Limilabs support</dc:creator>
				<category><![CDATA[Component]]></category>
		<category><![CDATA[Barcode.dll]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[WinForms]]></category>

		<guid isPermaLink="false">http://www.limilabs.com/blog/?p=2438</guid>
		<description><![CDATA[In this video you&#8217;ll learn how to: Download and install Barcode.dll barcode component. Create new WinForms application that references Barcode.dll barcode component. Darg &#038; drop barcode windows control Configure barcode windows control. Enjoy:]]></description>
			<content:encoded><![CDATA[<p>In this video you&#8217;ll learn how to:</p>
<ul>
<li>Download and install Barcode.dll <a href="http://www.limilabs.com/barcode">barcode component</a>.</li>
<li>Create new WinForms application that references Barcode.dll barcode component.</li>
<li>Darg &#038; drop barcode windows control</li>
<li>Configure barcode windows control.</li>
</ul>
<p>Enjoy:</p>
<p><object type="application/x-shockwave-flash" style="width:640px; height:505px;" data="http://www.youtube.com/v/17Z4PgklzAo?rel=0&amp;showsearch=0&amp;version=3&amp;modestbranding=1"><param name="movie" value="http://www.youtube.com/v/cU-NENna-Z4?rel=0&amp;showsearch=0&amp;version=3&amp;modestbranding=1" /><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.limilabs.com/blog/create-barcode-in-winforms-video/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Background processing in WinForms</title>
		<link>http://www.limilabs.com/blog/background-processing-in-winforms?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=background-processing-in-winforms</link>
		<comments>http://www.limilabs.com/blog/background-processing-in-winforms#comments</comments>
		<pubDate>Wed, 03 Feb 2010 16:00:59 +0000</pubDate>
		<dc:creator>Limilabs support</dc:creator>
				<category><![CDATA[Presentation]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[WinForms]]></category>

		<guid isPermaLink="false">http://www.limilabs.com/blog/?p=406</guid>
		<description><![CDATA[Many times developing windows applications, you&#8217;ll need to perform some operations in background. The problem you&#8217;ll face sooner or later is that those operations need to inform User Interface (UI) about their progress and completion. UI doesn&#8217;t like to be informed about anything from a different thread: you&#8217;ll get nasty &#8220;Cross-thread operation not valid&#8221; exception [...]]]></description>
			<content:encoded><![CDATA[<p>Many times developing windows applications, you&#8217;ll need to perform some operations in <strong>background</strong>.</p>
<p>The problem you&#8217;ll face sooner or later is that those operations need to<strong> inform User Interface</strong> (UI) about their <strong>progress </strong>and <strong>completion</strong>.</p>
<p>UI doesn&#8217;t like to be informed about anything from a different thread: you&#8217;ll get nasty &#8220;<strong>Cross-thread operation not valid</strong>&#8221; exception from WinForms controls, if you try.</p>
<p>Let&#8217;s take a look at the sample Presenter code:</p>
<pre class="brush: csharp;">
public void Start()
{
        TaskStatus taskStatus = this._backupService.CreateTask();
        taskStatus.Completed += BackupFinished;
        this._backupService.Start(taskStatus);
}
</pre>
<p><strong>TaskStatus</strong> contains single event Completed.<br />
What&#8217;ll do is that we&#8217;ll subscribe to this event to display some information on the View:</p>
<pre class="brush: csharp;">
public void BackupFinished(object sender, EventArgs e)
{
        // If the operation is done on different thread,
        // you'll get &quot;Cross-thread operation not valid&quot;
        // exception from WinForms controls here.
        this.View.ShowMessage(&quot;Finished!&quot;);
}
</pre>
<p>So, what are the options:</p>
<ul>
<li>Use <em>Control.BeginInvoke</em> in View &#8211; makes your code unreadable</li>
<li><a href="http://www.limilabs.com/blog/cross-thread-operations-with-postsharp">Use Control.BeginInvoke with PostSharp</a> &#8211; you need PostSharp</li>
<li><strong>SynchronizationContext</strong></li>
</ul>
<p>Lets examine the last concept as SynchronizationContext is not a well-know-class in the .NET world.<br />
Generally speaking this class is useful for synchronizing calls from worker thread to UI thread.</p>
<p>It has a static <em>Current</em> property that gets the synchronization context for the current thread or null if there is no UI thread (e.g. in Console application)</p>
<p>This is the <em>TaskStatus</em> class that utilizes <em>SynchronizationContext.Current</em> if it is not null:</p>
<pre class="brush: csharp;">
public class TaskStatus
{
    private readonly SynchronizationContext _context;

    public event EventHandler Completed = delegate { };

    public TaskStatus()
    {
        _context = SynchronizationContext.Current;
    }

    internal void OnCompleted()
    {
        Synchronize(x =&gt; this.Completed(this, EventArgs.Empty));
    }

    private void Synchronize(SendOrPostCallback callback)
    {
        if (_context != null)
            _context.Post(callback, null);
        else
            callback(null);
    }
};
</pre>
<p>Now lets see some tests.</p>
<p>First we&#8217;ll check if the event is executed:</p>
<pre class="brush: csharp;">
[Test]
public void Completed_RaisesCompleted()
{
    using(SyncContextHelper.No())
    {
        bool wasFired = false;
        TaskStatus status = new TaskStatus();
        status.Completed += (sender, args) =&gt; { wasFired = true; };
        status.OnCompleted();
        Assert.IsTrue(wasFired);
    }
}
</pre>
<p>The following test shows that in <strong>WindowsForms application</strong>, although operation is executed on different thread, Completed<strong> event is routed</strong> back (using windows message queue) <strong>to the UI thread</strong>:</p>
<pre class="brush: csharp;">
[Test]
public void Completed_WithSyncContext_IsExecutedOnSameThread()
{
    using (SyncContextHelper.WinForms())
    {
         int completedOnThread = -1;
         int thisThread = Thread.CurrentThread.GetHashCode();

         TaskStatus status = new TaskStatus();
         status.Completed += (sender, args) =&gt;
             {
                 completedOnThread =
                    Thread.CurrentThread.GetHashCode();
             };

         Scenario.ExecuteOnSeparateThread(status.OnCompleted);

         // process messages send from background thread
         // (like Completed event)
         Application.DoEvents();

         Assert.AreEqual(thisThread, completedOnThread);
    }
}
</pre>
<p>When there is no SynchronizationContext (<em>SynchronizationContext.Current</em> == <em>null</em>) <em>Completed</em> event is executed on the different thread:</p>
<pre class="brush: csharp;">
[Test]
public void Completed_InMultiThreadedScenario_IsExecuedOnDifferentThread()
{
    using(SyncContextHelper.No())
    {
        int completedOnThread = -1;
        int thisThread = Thread.CurrentThread.GetHashCode();

        TaskStatus status = new TaskStatus();
        status.Completed += (sender, args) =&gt;
            {
                completedOnThread =
                    Thread.CurrentThread.GetHashCode();
            };

        Scenario.ExecuteOnSeparateThread(status.OnCompleted);

        Assert.AreNotEqual(thisThread, completedOnThread);
    }
}
</pre>
<p>Finally unit test helper classes:</p>
<pre class="brush: csharp;">
public class SyncContextHelper : IDisposable
{
    private readonly SynchronizationContext _previous;

    private SyncContextHelper(SynchronizationContext context)
    {
        _previous = SynchronizationContext.Current;
        SynchronizationContext.SetSynchronizationContext(context);
    }

    public static SyncContextHelper WinForms()
    {
        return new SyncContextHelper(
            new WindowsFormsSynchronizationContext());
    }

    public static SyncContextHelper No()
    {
        return new SyncContextHelper(null);
    }

    public void Dispose()
    {
        SynchronizationContext.SetSynchronizationContext(_previous);
    }
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.limilabs.com/blog/background-processing-in-winforms/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cross-thread operations with PostSharp</title>
		<link>http://www.limilabs.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.limilabs.com/blog/cross-thread-operations-with-postsharp#comments</comments>
		<pubDate>Tue, 26 Jan 2010 15:00:43 +0000</pubDate>
		<dc:creator>Limilabs support</dc:creator>
				<category><![CDATA[Presentation]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[PostSharp]]></category>
		<category><![CDATA[WinForms]]></category>

		<guid isPermaLink="false">http://www.limilabs.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.limilabs.com/blog/cross-thread-operations-with-postsharp/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

