Maximizing.ASP.dot.NET.Real.World.ObjectOriented.Development [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Maximizing.ASP.dot.NET.Real.World.ObjectOriented.Development [Electronic resources] - نسخه متنی

Jeffrey Putz

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Threading



Most computers can do more than one thing at once. This is accomplished by running certain programs or components in their own threads. The CPU divides its time between the various threads running, doing some work on one thread during its allotted slice of time and then moving to the next. At any given time, your computer is probably running several hundred different threads, especially if you have several applications open at once.


In the world of Web applications, threading isn't generally a concern for us because most of what we do happens in the context of an incoming request and the response we send back to the browser. A page is stateless; after it has been rendered and sent off to the browser, the server forgets about it forever. This is very different from a Windows application, where several things might be going on at once. For example, if an FTP program worked entirely in one thread, you wouldn't be able to press a Cancel button because the program would be busy sending or receiving a file. By executing that transfer in its own thread, the rest of the application remains responsive.


Web developers may encounter some special needs from time to time that do require threading. Say your application needs to send email to ten different people when a record is updated in your database. Sending all ten messages in the page will cause a delay in sending the response (the page) to the user. That's probably not acceptable.


Another frequent need is to perform some kind of action on a regular interval. A good example of this is to delete incomplete shopping cart data from a database after it has aged a certain amount of time.


Let's start with an example where we perform some kind of action outside of a page. Listing 17.5 shows how we can launch a simple method in its own thread, letting the rest of the page continue its execution at the same time.


Listing 17.5. Launching a new thread


C#



using System;
using System.Threading;
using System.Web;
public partial class ThreadFun_aspx
{
public void Page_Load(object sender, EventArgs e)
{
ThreadStart ts = new ThreadStart(RebelThread);
Thread t = new Thread(ts);
t.Start();
}
private void RebelThread()
{
// do something here
}
}


VB.NET



Imports System
Imports System.Threading
Imports System.Web
Public Class ThreadFun_aspx
Public Sub Page_Load(sender As Object, e As EventArgs)
Dim ts As New ThreadStart(RebelThread)
Dim t As New Thread(ts)
t.Start()
End Sub
Private Sub RebelThread()
' do something here
End Sub
End Class


Launching the method RebelThread() in its own thread is a three-step process. First, we create a ThreadStart delegate, passing in the name of the method as its only parameter. Next we create the THRead object, passing in the THReadStart object. Finally, we call the thread's Start() method, and the method code fires on its own. The page finishes its execution, and (if it's still working) the method continues on its own.





.NET v2.0 adds a new ParameterizedThreadStart delegate that lets you pass in a parameter to the Start() method, which is in turn passed to the method you want to execute in a new thread. The method you want to run should have a single object parameter. This could be a handy way to pass in the HttpContext.Current object to the new thread, where you'll find information about the original request and have access to Cache. Be sure to cast the object from the parameter to whatever type you'll need.Chapter 8, "HttpHandlers and HttpModules," that a module must implement an Init() method, which is called when the application is first run. In this method, we'll assign a new Timer to a static member in the module, based on the method that we want to run at a given time interval. For good housekeeping, we'll dispose of the Timer in the module's required Dispose() method. The basic syntax for all this is shown in Listing 8.7 in Chapter 8).


Listing 17.6. Creating a Timer in an HttpModule


C#


[View full width]



using System;
using System.Web;
using System.Threading;
public class MyHttpModule : IHttpModule
{
public void Init(HttpApplication application)
{
myTimer = new Timer(new TimerCallback(this.TimerMethod),
application.Context, 60000,
60000);
}
public void Dispose()
{
myTimer.Dispose();
}
static Timer myTimer;
private void TimerMethod(object sender)
{
HttpContext context = (HttpContext)sender;
// do something here
}
}


VB.NET



Imports System
Imports System.Web
Imports System.Threading
Public Class MyHttpModule
Implements IHttpModule
Public Sub Init(application As HttpApplication)
myTimer = New Timer(New TimerCallback(Me.TimerMethod), _
application.Context, 60000, 60000)
End Sub
Public Sub Dispose()
myTimer.Dispose()
End Sub
Private Shared myTimer As Timer
Private Sub TimerMethod(sender As Object)
Dim context As HttpContext = CType(sender, HttpContext)
' do something here
End Sub
End Class


According to the IHttpModule interface, the Init() method must take a parameter of the HttpApplication type, which provides us with a reference to the application. We have a static Timer object declared, which is what we'll use to hold the Timer we declare in Init(). The method that we want to run in the timer must take an object parameter. This is required by any method that will be declared as a TimerCallback delegate.


The actual declaration of our timer takes four parameters. The first is a new TimerCallback delegate, which is created with our TimerMethod() method as a parameter. Note that we don't include the parameters or parentheses when naming the method. The second parameter for our Timer constructor is an object that is used to pass along application state. Because we have a reference to the application as a parameter for the Init() method, we'll pass in the application's Context property. The last two parameters are integers representing the number of milliseconds that should pass before we start the timer, and then the time that should pass between invocations of our method. We chose 60 seconds (60,000 milli seconds) for both on our example.


Because it's often useful to get various properties from the application, especially its Cache property, we can cast the object parameter of our recurring method to HttpContext, which is what we passed in when we created the timer.



/ 146