当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > .NET中多线程的同步资源访问

ASP.NET
如何在ASP.NET中使用SmtpMail发送邮件
在VB.NET中利用Split和Replace函数计算字数
Attribute应用:简化ANF自定义控件初始化过程
ASP.NET 2.0移动开发入门之使用样式
ASP.NET 2.0中使用OWC生成图表
ASP.NET 2.0中控件的简单异步回调
一个无法捕获ADO.NET Dataset的内存错误
深入解读ADO.NET2.0的十大最新特性
.Net平台下的分布式缓存设计
ASP.NET全局异常处理浅析
ASP.NET 2.0中文验证码的实现
浅析.NET平台编程语言的未来走向
.net 框架程序设计收藏
使用ASP.NET MVC Futures 中的异步Action
详解.NET中的XmlReader与XmlWriter
关于.NET中的Server push技术
asp.net页面执行机制
对比JSP和ASP.NET的存储过程
.NET 4.0不会包含System.Shell.CommandLine
ASP.NET十个有效性能优化的方法

ASP.NET 中的 .NET中多线程的同步资源访问


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 186 ::
收藏到网摘: n/a

在应用程序中使用多个线程的一个好处是每个线程都可以异步执行。对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应。对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力。否则,在完全满足前一个请求之前,将无法处理每个新请求。

然而,线程的异步特性意味着必须协调对资源(如文件句柄、网络连接和内存)的访问。否则,两个或更多的线程可能在同一时间访问相同的资源,而每个线程都不知道其他线程的操作。结果将产生不可预知的数据损坏。

让我们先来看一片java的例子:多线程未同步可能导致的问题及其解决方案
下面是C#的代码
transfer方法
public void transfer(int from, int to, double amount) {
            if (accounts[from] < amount) return;
            Console.WriteLine(System.Threading.Thread.CurrentThread.Name);
            accounts[from] -= amount;
            Console.WriteLine("{0:F2} from {1} to {2}", amount, from, to);
            accounts[to] += amount;
            Console.WriteLine("Total Balance: {0:F2}", getTotalBalance());
        }run方法
public void run() {
            Random rand;
            try {
                while (true) {
                    rand = new Random();
                    int toAccount = rand.Next(bank.size);
                    double amount = rand.NextDouble() * maxAmount;
                    bank.transfer(fromAccount, toAccount, amount);
                    System.Threading.Thread.Sleep(rand.Next(DELY));
                }
            }
            catch { }
        }
这个问题在.net中同样存在,对于.net有下面几中解决方案可以确保安全的执行多线程处理:

1)lock 关键字
2)监视器
3)同步事件和等待句柄
4)Mutex 对象

这里我们只说一下使用lock关键字,如果需要更多信息,请访问msdn:
ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_csref/html/413e1f28-a2c5-4eec-8338-aa43e7982ff4.htm

lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。
lock 语句以关键字 lock 开头,它有一个作为参数的对象,在该参数的后面还有一个一次只能由一个线程执行的代码块。例如:

public void Function()
{
    System.Object lockThis = new System.Object();
    lock(lockThis)
    {
        // Access thread-sensitive resources.
    }
}
修改run方法
public void run() {
            Random rand;
            try{
                while (true) {
                    lock (bank) {
                        rand = new Random();
                        int toAccount = rand.Next(bank.size);
                        double amount = rand.NextDouble() * maxAmount;
                        bank.transfer(fromAccount, toAccount, amount);
                        System.Threading.Thread.Sleep(rand.Next(DELY));
                    }
                }
            }
            catch{}
        }使用lock关键字锁住了bank对象的实例,lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放.
这里使用lock需要注意的是:
应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)、lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:
1.如果实例可以被公共访问,将出现 lock (this) 问题。
2.如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题
3.由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题.

就我个人而言,我觉得多线程如果要访问共享数据必须同步