• 全部
  • C#综合技术
  • C#互联网桌面应用
  • AppLauncher
  • WinForm&WPF
  • C#开发新技术
  • 问答

如何控制只能有一个线程访问一个类?

jackiedlh2 2004-10-28 02:59:09
我的一个类要保持状态,因此只能有一个线程访问它。
我的程序中会产生很多"未名"的线程,如BeginInvoke,异步访问web service等
如何在我的这个类中进行控制只能有有个线程来访问,其他线程进行等待呢?
...全文
54 点赞 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
jackiedlh2 2004-10-28
to brightheroes(闭关|那一剑的风情):
我的类实现一个singleton的实例,怎么Lock这个实例?每个方法中加lock(this)?
回复
brightheroes 2004-10-28
lock 关键字可将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:

lock(expression) statement_block
其中:

expression
指定要锁定的对象。expression 必须是引用类型。
通常,如果要保护实例变量,则 expression 为 this;如果要保护 static 变量(或者如果临界区出现在给定类的静态方法中),则 expression 为 typeOf (class)。

statement_block
临界区的语句。
备注
lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入一个锁定代码,则它将在释放该对象前一直等待(块)。

8.12 lock 语句对 lock 进行了讨论。

示例 1
下例显示的是在 C# 中使用线程的简单示例。

// statements_lock.cs
using System;
using System.Threading;

class ThreadTest
{
public void runme()
{
Console.WriteLine("runme called");
}

public static void Main()
{
ThreadTest b = new ThreadTest();
Thread t = new Thread(new ThreadStart(b.runme));
t.Start();
}
}
输出
runme called
示例 2
下例使用线程和 lock。只要 lock 语句存在,语句块就是临界区并且 balance 永远不会是负数。

// statements_lock2.cs
using System;
using System.Threading;

class Account
{
int balance;

Random r = new Random();

public Account(int initial)
{
balance = initial;
}

int Withdraw(int amount)
{

// This condition will never be true unless the lock statement
// is commented out:
if (balance < 0)
{
throw new Exception("Negative Balance");
}

// Comment out the next line to see the effect of leaving out
// the lock keyword:
lock (this)
{
if (balance >= amount)
{
Console.WriteLine("Balance before Withdrawal : " + balance);
Console.WriteLine("Amount to Withdraw : -" + amount);
balance = balance - amount;
Console.WriteLine("Balance after Withdrawal : " + balance);
return amount;
}
else
{
return 0; // transaction rejected
}
}
}

public void DoTransactions()
{
for (int i = 0; i < 100; i++)
{
Withdraw(r.Next(1, 100));
}
}
}

class Test
{
public static void Main()
{
Thread[] threads = new Thread[10];
Account acc = new Account (1000);
for (int i = 0; i < 10; i++)
{
Thread t = new Thread(new ThreadStart(acc.DoTransactions));
threads[i] = t;
}
for (int i = 0; i < 10; i++)
{
threads[i].Start();
}
}
}
回复
jackiedlh2 2004-10-28
to ckwangfg(孤独的狼)
那需要在该类的每个方法中加上这个状态变量,当线程访问结束,还原状态
因为我的类采用了singleton模式,不能新建实例
回复
ckwangfg 2004-10-28
类中增加一个静态变量表示访问状态
每次线程在使用该类之前检查一下状态
回复
brightheroes 2004-10-28
lock
回复
相关推荐
发帖
C#
创建于2007-09-28

10.5w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2004-10-28 02:59
社区公告

让您成为最强悍的C#开发者