<?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; WinForms</title>
	<atom:link href="http://www.lesnikowski.com/blog/tag/winforms/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>New Barcode.dll tutorial videos</title>
		<link>http://www.lesnikowski.com/blog/new-barcode-dll-tutorial-videos/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=new-barcode-dll-tutorial-videos</link>
		<comments>http://www.lesnikowski.com/blog/new-barcode-dll-tutorial-videos/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 11:16:38 +0000</pubDate>
		<dc:creator>Pawel Lesnikowski</dc:creator>
				<category><![CDATA[Component]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[barcode]]></category>
		<category><![CDATA[Barcode.dll]]></category>
		<category><![CDATA[WinForms]]></category>

		<guid isPermaLink="false">http://www.lesnikowski.com/blog/?p=1065</guid>
		<description><![CDATA[New Barcode.dll tutorial videos are out. You can watch them here: Barcode.dll ASP.NET tutorial video. Barcode.dll Windows Forms tutorial video. Barcode.dll Windows Forms printing tutorial video.]]></description>
			<content:encoded><![CDATA[<p>New <strong>Barcode.dll tutorial videos</strong> are out. You can watch them here: </p>
<p><a href="http://www.lesnikowski.com/barcode/tutorial/WebTutorial.aspx"><img src="http://www.lesnikowski.com/blog/wp-content/uploads/2010/04/MailVideoThumb.jpg" alt="Barcode.dll ASP.NET tutorial video" width="64" height="51" class="alignnone size-full wp-image-801" /> Barcode.dll ASP.NET tutorial video</a>.</p>
<p><a href="http://www.lesnikowski.com/barcode/tutorial/WinFormsTutorial.aspx"><img src="http://www.lesnikowski.com/blog/wp-content/uploads/2010/04/MailVideoThumb.jpg" alt="Barcode.dll Windows Forms tutorial video" width="64" height="51" class="alignnone size-full wp-image-801" /> Barcode.dll Windows Forms tutorial video</a>.</p>
<p><a href="http://www.lesnikowski.com/barcode/tutorial/WinFormsPrintingTutorial.aspx"><img src="http://www.lesnikowski.com/blog/wp-content/uploads/2010/04/MailVideoThumb.jpg" alt="Barcode.dll Windows Forms printing tutorial video" width="64" height="51" class="alignnone size-full wp-image-801" /> Barcode.dll Windows Forms printing tutorial video</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lesnikowski.com/blog/new-barcode-dll-tutorial-videos/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Background processing in WinForms</title>
		<link>http://www.lesnikowski.com/blog/background-processing-in-winforms/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=background-processing-in-winforms</link>
		<comments>http://www.lesnikowski.com/blog/background-processing-in-winforms/#comments</comments>
		<pubDate>Wed, 03 Feb 2010 16:00:59 +0000</pubDate>
		<dc:creator>Pawel Lesnikowski</dc:creator>
				<category><![CDATA[Presentation]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[WinForms]]></category>

		<guid isPermaLink="false">http://www.lesnikowski.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.lesnikowski.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.lesnikowski.com/blog/background-processing-in-winforms/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

