我正在编写简单的银行帐户教程程序。对于每个注册的新客户,对于新的ID,帐号将增加1。 我在“ C#Mueller”书中看到了示例。我很好奇,如果这是执行此操作的正确方法,它将如何处理并发注册?是否有更好的方法来处理此问题,例如使用Singletons或全局变量,内存缓存?这样的项目如何在现实世界的应用程序中处理?
public class BankAccount
{
private static int _nextAccountNumber = 1000;
private int _accountNumber;
private double _balance;
public void InitBankAccount()
{
_accountNumber = ++_nextAccountNumber;
_balance = 0.0;
}
public void Deposit(decimal amount)
{
_balance += amount;
}
etc...
此站点也很有用:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/lock-statement
答案 0 :(得分:4)
您实际上可以在此处使用Interlocked.Increment,它返回增加的金额。它应该是线程安全的,在docs链接中有一个示例将其用于此目的。
using System.Threading;
...
public void InitBankAccount()
{
_accountNumber = Interlocked.Increment(ref _nextAccountNumber);
_balance = 0.0;
}
答案 1 :(得分:2)
您正在做什么,但不是线程安全的。在注释中提到的thepirat000,您可以使用lock语句。
private static object acctNumLock = new object();
…
lock(acctnumLock) {
_accountNumber = ++_nextAccountNumber;
}
您还应该考虑使用效率更高的Interlock.Increment方法。使用lock语句可以“锁定”(一次仅允许一个线程访问)一块语句。 Interlock.Increment是一个原子操作,它只做一件事情(即增加一个值),但是这样做的目的是确保在线程切换之前完成该操作。两者都提供线程安全性。
有更好的方法吗?这是一个很难回答的问题,因为这取决于您要执行的操作。我怀疑实际的银行应用程序会占用数据库锁并使用特定的算法来生成帐号(即更为复杂的过程)。如果您只是尝试为简单的应用程序生成唯一值,那么您应该可以正常工作。