Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Architecture
ASP.NET
ASP.NET MVC
ASP.NET WebForms
Azure
B2B (Business Integration)
Bing
BizTalk
Book Excerpts
Build and Deploy
C#
C++
ClickOnce
Cloud Computing
Code Contracts
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Design Patterns
Development Process
Display Technologies
Distributed Computing
DotNetNuke
DSL
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Git
Graphics
Internet Explorer 8.0
Interviews
iPhone
Iron Ruby
Java
Java Script
jQuery
LINQ
Linux
Mac OS X
MDX
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Dynamics
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
MsBuild
Network
NHibernate
Object Oriented Development
Odata
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
Podcasts
Post Mortem
PowerPoint
Print/Output
Prism
Product News
Product Reviews
Project Management
Python
Q&A
Rails
Rake
Reporting Services
REST
RIA Services
Ruby
Ruby on Rails
Search
Security
Services
SharePoint
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server CE/AnyWhere/Mobile/Compact
SSIS
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
Tips
UI Design
UML
User Groups
VB Script
VB.NET
Version Control
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WF
Whitepapers
Windows 7
Windows Azure
Windows Live
Windows Server
Windows Vista
WinForms
Workflow
WPF
XAML
XML
XNA
XSLT



Hacker Halted


 


Devscovery

Reader rating:
Click here to read 13 comments about this article.
Article source: CoDe (2004 - March/April)


Article Pages:  1  2 3 4 5 - Next >


Asynchronous Windows Forms Programming

Windows Forms applications often require some sort of asynchronous invocation option.You rarely want to block the user interface while a lengthy operation executes in the background. Windows Forms pose a set of complicated design and implementation issues when it comes to asynchronous method invocation and multithreading due to the underlying Windows messages processing. Although .NET does provide a uniform asynchronous invocation mechanism (described in my article, "Asynchronous .NET Programming", CoDe Magazine, May 2003) you cannot apply it as-is in a Windows Forms application. To address this problem, the next version of .NET (version 2.0, code-name Whidbey) provides a new component designed to ease the task of developing asynchronous Windows Forms applications. This article starts by describing the current asynchronous programming model available to Windows Forms developers. Then, not only does this article describe the Whidbey solution, it also provides a .NET 1.1 implementation of the solution so that you can take advantage of this superior programming model today and ease the transition into Windows Forms 2.0 in the future.

Windows Forms 1.1 and Asynchronous Execution

Developers commonly use a delegate to invoke an asynchronous method call in .NET. Each delegate provides a BeginInvoke() and EndInvoke() method. To invoke a method asynchronously, wrap it in a delegate and call BeginInvoke() on the delegate. The delegate will delegate the act of invoking the method to a thread from the thread pool, thus making it asynchronous towards the caller. You have several options available that let you deal with the method completion, from fire-and-forget to polling, but the most common option (and the one best fitting an event-driven application such as a Windows Forms application) is to use a callback method. When the asynchronous operation is completed, you can have .NET call back into a method you provide, where you can call EndInvoke() to harvest returned values or deal with errors. The thread from the thread pool will do the callback after it executes the method.

"
Windows Forms poses a set of complicated design and implementation issues when it comes to asynchronous method invocation and multithreading.
"

You identify the completion callback method using a delegate of the type AsyncCallback that you pass to the BeginInvoke() call used to dispatch the method asynchronously. You need to be familiar with a few additional details including how to gain access to the original delegate used to invoke the call from within the completion callback, but in general, the programming model just described is sufficient for most applications, except when it comes to Windows Forms. Why are Windows Forms the exception? First, any decent client application should want to display some progress or indication of the current status of the asynchronous task to the user. In fact, you may want to pass the progress report to multiple parties?you may need to update both the status bar and a progress bar. Second, you may want to allow the user to cancel the asynchronous method invocation in progress.

The crucial limiting factor in implementing these features is the thread affinity Windows Forms controls and forms have to the underlying thread that created them. All Windows messages are actually messages between threads, and each thread has its own message queue. Each and every thread message can only be processed on the thread it belongs to. When a thread creates a window, that window's messages are actually messages destined for the message queue of the creating thread. Consequently, all windows (such as Windows Forms forms and controls) can only process messages on the thread that created them. Method calls on Windows Forms forms and controls often result internally with posting of at least one such message.

In a simple Windows Forms application (such as the one created by the Visual Studio .NET application wizard), all forms and controls execute on the same thread?the primordial thread used to launch the application by calling Main()?so those forms and controls can freely call each other's methods.

When a Windows Forms window invokes a call asynchronously (using a delegate), that call executes on a worker thread from the thread pool, not the thread that created the window. The completion callback method is also executed on the worker thread. As a result, the completion callback method should never update the user interface directly because that would be calling a Windows Forms form or control on a different thread from the thread that created it. Similarly, progress reports triggered by the worker thread are not allowed to directly update controls such as a progress bar. In all these cases, you must marshal the call from the worker thread to the user interface thread. This is exactly what the ISynchronizeInvoke interface, defined in the System.ComponentModel namespace, is designed to do:

public interface ISynchronizeInvoke 
{
   object Invoke(Delegate method,object[] args);
   IAsyncResult BeginInvoke(Delegate method,
                            object[] args);
   object EndInvoke(IAsyncResult result);
   bool InvokeRequired {get;}
}

ISynchronizeInvoke provides a generic and standard mechanism for marshaling calls between threads.

For example, imagine a client on thread T1 and an object on thread T2. If the object implements ISynchronizeInvoke, the client on thread T1 can call ISynchronizeInvoke's Invoke() on the object. The implementation of Invoke() will block the calling thread (T1), marshal the call to T2, execute the call on T2, marshal the returned values to T1, and return control to the calling client on T1. Invoke() accepts a delegate targeting the method to invoke on T2, and a generic array of objects as parameters.

Because the call is marshaled to a different thread from that of the caller, you might want to be able to invoke it asynchronously. Microsoft created the BeginInvoke() and EndInvoke() methods to provide this functionality, but I won't address these methods in this article.

In addition, because ISynchronizeInvoke can be called on the same thread as the thread the caller tries to redirect the call to; the caller can check the InvokeRequired property. If it returns false, then the caller can call the object methods directly.

&

By: Juval Lowy

Juval Löwy is a software architect and the principal of IDesign, a consulting and training company focused on .NET architecture consulting and advanced .NET training. This article contains excerpts from his latest book (Programming .NET Components 2nd Edition (O'Reilly, 2005). Juval is a frequent presenter at development conferences and Microsoft's Regional Director for the Silicon Valley.

Over the last three years Juval has been part of the Strategic Design Review process for .NET 2.0.

Microsoft recognized Juval as a Software Legend as one of the world's top .NET experts and industry leaders.

Contact him at www.idesign.net

Fast Facts

Adding asynchronous invocation to Windows Forms application is not trivial, and it complicates the programming model. .NET 2.0 addresses this with a new component called BackgroundWorker. This article discuses the problem Windows Forms developers face today and the .NET 2.0 solution. You'll learn how to implement BackgroundWorker in Visual Studio .NET 2003 so you could benefit from its elegant programming model, and transition transparently into Windows Forms 2.0 in the future.



Article Pages:  1  2 3 4 5 - Next Page: 'Windows Forms 1.1 and Asynchronous Execution (cont.)' >>

Page 1: Asynchronous Windows Forms Programming
Page 2: Windows Forms 1.1 and Asynchronous Execution (cont.)
Page 3: .NET 2.0 BackgroundWorker
Page 4: Implementing BackgroundWorker with .NET 1.1
Page 5: Implementing BackgroundWorker with .NET 1.1 (cont.)

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
4.5 out of 5

78 people have rated this article.

      Free Webinar

 

DevReach