Update atm balance - c#-4.0

I'm trying make the make current balance method update its balance after a withdrawal method is called so that it becomes the starting balance for any subsequent withdrawal.I don't know what i'm doing wrong.Thanks.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
public class Customer
{
private double deposit;
private double balance;
static double bankCharge = 0.50;
public Customer(double depo)
{
if (depo > 2000)
{
Console.WriteLine("deposit cannot be morethan 2000");
}
else
{
this.deposit += depo;
}
}
public void setDeposit(double depo)
{
if (depo > 2000)
{
Console.WriteLine(" Sorry, you cannot deposit morethan 2000");
}
else
{
this.deposit+= depo;
}
}
public double currentBalance()
{
this.balance= this.deposit;
//this.balance+=this.balance;
return this.balance;
}
public double Withdrawal()
{
int amount;
bool passed;
do
{
Console.WriteLine("How much do you want to withdraw?");
passed = int.TryParse(Console.ReadLine(), out amount);
if ((!passed) || (amount % 5 != 0))
{
Console.WriteLine("Wrong input,No decimals please,Enter in multiples of 5, Try again");
}
} while (!passed || amount % 5 != 0);
double charges = amount + bankCharge; // amount to be withdrawn + the bank charge
Console.WriteLine("charges are {0}", charges);
// Console.WriteLine("Your current balance is {0}", this.currentBalance());
if (charges > this.currentBalance())
{
Console.WriteLine("Sorry, you do not have enough money to perform this transaction");
}
else
{
Console.WriteLine("Your current balance is {0}", this.balance);
this.balance-= charges; // withdrawal done
Console.WriteLine(" balance after transaction/charges is={0} ",this.balance);
}
return this.balance;
}
}
class Program
{
static void Main()
{
Customer lee = new Customer(500);
lee.setDeposit(2000);
lee.setDeposit(400);
//Console.WriteLine("the withdraw function returns this amount {0}", lee.Withdrawal());
Console.WriteLine(lee.Withdrawal());
Console.WriteLine(lee.currentBalance());
}
}

Code is now working the way i want it.I got rid of the implementation in currentBalance method.I set this.balance to deposit in the constructor and setDeposit method which updates balance every time a deposit is made.Balance equally updates every time the withdrawal method is called and withdrawal is made.That was my initial challenge;balance didn't update after withdrawal.It is fixed now.You may close.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
public class Customer
{
private double deposit;
private double balance;
static double bankCharge = 0.50;
public Customer(double depo)
{
if (depo > 2000)
{
Console.WriteLine("deposit cannot be morethan 2000");
}
else
{
this.deposit += depo;
this.balance = this.deposit;
}
}
public void setDeposit(double depo)
{
if (depo > 2000)
{
Console.WriteLine(" Sorry, you cannot deposit morethan 2000");
}
else
{
this.deposit += depo;
this.balance = this.deposit;
}
}
public double currentBalance()
{
return this.balance;
}
public double Withdrawal()
{
int amount;
bool passed;
do
{
Console.WriteLine("How much do you want to withdraw?");
passed = int.TryParse(Console.ReadLine(), out amount);
if ((!passed) || (amount % 5 != 0))
{
Console.WriteLine("Wrong input,No decimals please,Enter in multiples of 5, Try again");
}
} while (!passed || amount % 5 != 0);
double charges = amount + bankCharge;
Console.WriteLine("charges are {0}", charges);
Console.WriteLine("Your current balance is {0}", this.balance);
if (charges > this.balance)
{
Console.WriteLine("Sorry, you do not have enough money to perform this transaction");
}
else
{
this.balance = this.balance - charges;
}
return this.balance;
}
}
class Program
{
static void Main()
{
Customer lee = new Customer(500);
lee.setDeposit(2000);
lee.setDeposit(400);
lee.setDeposit(250);
lee.setDeposit(1850);
// Console.WriteLine( lee.Withdrawal());
//Console.WriteLine(lee.Withdrawal());
Console.WriteLine("Balance before withdawal is {0}", lee.currentBalance());
Console.WriteLine( " Your balance after withdawal is {0}",lee.Withdrawal());
Console.WriteLine("Starting balance for next transaction is {0}",lee.currentBalance());
Console.WriteLine("*******************************************************");
Console.WriteLine("Balance before withdawal is {0}", lee.currentBalance());
Console.WriteLine(" Your balance after withdawal is {0}", lee.Withdrawal());
Console.WriteLine("Starting balance for next transaction is {0}", lee.currentBalance());
}
}

Related

Sound won't play at a specific time in unity

I am trying to make a sound play with the timer goes to 3, 2, 1.
My timer starts at ten and has a three second delay. If I use the following code:
if (tl.myCoolTimer == 10)
{
print("Play Sound");
myAudioSource.Play();
}
It plays the Beep over and over again until the game starts and the counter goes below 10.
If I use the code:
if (tl.myCoolTimer == 3)
{
print("Play Sound");
myAudioSource.Play();
}
It doesn't play the sound at all. It doesn't even print the print statement.
I literally only changed the number. I am not sure why this isn't working.
I have also tried setting it to 3f to see if it is a float issue.
Timer Scripts
This is the starting Timer. it counts down to 3 (then the game starts)
public Text startGameTimerText;
public float startGameTimer = 3;
public void Start ()
{
startGameTimerText = GetComponent<Text> ();
}
public void Update ()
{
startGameTimer -= Time.deltaTime;
startGameTimerText.text = startGameTimer.ToString ("f1");
if (startGameTimer < 0) {
GameObject.Find ("GameStartTimer").SetActive (false);
}
}
This is the Game Timer It starts at 10 and counts down to 0.
public StartGameTimer gt; //this is the script the other timer is on
public Text timerText;
public float myCoolTimer = 10;
public void Start ()
{
timerText = GetComponent<Text> ();
}
public void Update ()
{
if (gt.startGameTimer > 0) {
myCoolTimer = 10;
} else {
myCoolTimer -= Time.deltaTime;
timerText.text = myCoolTimer.ToString ("f1");
}
}
Thanks Joe for the help. Here was my final answer. I know it is hacked, but I haven't figured out the Invoke thing yet. When I set the into it kept playing the entire time it was at "3", so i need to make it play only once.
private AudioSource myAudioSource;
public bool isSoundPlayed;
void Start()
{
myAudioSource = GetComponent<AudioSource>();
isSoundPlayed = false;
}
void Update()
{
if((int)tl.myCoolTimer == 3)
{
if (isSoundPlayed == false)
{
myAudioSource.Play();
isSoundPlayed = true;
}
return;
}
if ((int)tl.myCoolTimer == 2)
{
if (isSoundPlayed == true)
{
myAudioSource.Play();
isSoundPlayed = false;
}
return;
}
if ((int)tl.myCoolTimer == 1)
{
if (isSoundPlayed == false)
{
myAudioSource.Play();
isSoundPlayed = true;
}
return;
}
}

how to generate sequence number using c# in window application

private string GenerateID()
{
}
private void auto()
{
AdmissionNo.Text = "A-" + GenerateID();
}
with prefix of A like below
A-0001
A-0002 and so on .
You can use below code.
private string GenerateId()
{
int lastAddedId = 8; // get this value from database
string demo = Convert.ToString(lastAddedId + 1).PadLeft(4, '0');
return demo;
// it will return 0009
}
private void Auto()
{
AdmissionNo.Text = "A-" + GenerateId();
// here it will set the text as "A-0009"
}
Look at this
public class Program
{
private static int _globalSequence;
static void Main(string[] args)
{
_globalSequence = 0;
for (int i = 0; i < 10; i++)
{
Randomize(i);
Console.WriteLine("----------------------------------------->");
}
Console.ReadLine();
}
static void Randomize(int seed)
{
Random r = new Random();
if (_globalSequence == 0) _globalSequence = r.Next();
Console.WriteLine("Random: {0}", _globalSequence);
int localSequence = Interlocked.Increment(ref _globalSequence);
Console.WriteLine("Increment: {0}, Output: {1}", _globalSequence, localSequence);
}
}
Whether it is an windows application or not is IMHO not relevant. I'd rather care about thread safety. Hence, I would use something like this:
public sealed class Sequence
{
private int value = 0;
public Sequence(string prefix)
{
this.Prefix = prefix;
}
public string Prefix { get; }
public int GetNextValue()
{
return System.Threading.Interlocked.Increment(ref this.value);
}
public string GetNextNumber()
{
return $"{this.Prefix}{this.GetNextValue():0000}";
}
}
This could easily be enhanced to use the a digit count. So the "0000" part could be dynamically specified as well.

Transaction Module for a Banking app - Is Answered

I need help in Transaction Class:
The transaction class with contain the following data:
A counter to track the number of transactions. Increment for every deposit or
withdrawal made. A customer is allowed to make up to 5 transactions on a single login.
o A history of the 5 possible transactions. This will be an array of dollar amounts where a
negative amount is a withdrawal and a positive number is a deposit. Clear the history
each time a customer logs in.
Transaction objects will perform the following:
o Update history to reflect any transaction made when a user is logged in. Keep track of
each transaction value made as described above in the transaction data section. After
each transaction, increment the transaction counter.
o Clear history of all amounts stored and reset the transaction count
Menu Class
Account[] myCustAcc = new Account[10];
Transaction myCustTrans = new Transaction();
string adminInput = "" adminName = "adm1";
int pinInput = 0, adminChoice = 0,adminPin = 9999,user = 0, input, custCount = 0;
Boolean adminQuit = false;
Boolean appQuit = false;
myCustAcc[0] = new Account();
myCustAcc[0].setCustomerFirstName("Sneha");
myCustAcc[0].setCustomerLastName("Dadhania");
myCustAcc[0].setCustomerAddress("2323 S Dobson Rd");
myCustAcc[0].setCustomerState("AZ");
myCustAcc[0].setCustomerZip(85001);
myCustAcc[0].setCustomerUserName("SMD28");
myCustAcc[0].setCustomerPin(3333);
myCustAcc[0].setCustomerBalance(87000);
custCount++;
myCustAcc[1] = new Account();
myCustAcc[1].setCustomerFirstName("Justine");
myCustAcc[1].setCustomerLastName("Timberlake");
myCustAcc[1].setCustomerAddress("TriBeca, New York. ");
myCustAcc[1].setCustomerState("NY");
myCustAcc[1].setCustomerZip(11013);
myCustAcc[1].setCustomerUserName("JTL00");
myCustAcc[1].setCustomerPin(8989);
myCustAcc[1].setCustomerBalance(34);
custCount++;
myCustAcc[2] = new Account();
myCustAcc[2].setCustomerFirstName("Guest");
myCustAcc[2].setCustomerLastName("Ghost");
myCustAcc[2].setCustomerAddress("Ghost Street");
myCustAcc[2].setCustomerState("CO");
myCustAcc[2].setCustomerZip(87655);
myCustAcc[2].setCustomerUserName("GG111");
myCustAcc[2].setCustomerPin(1111);
myCustAcc[2].setCustomerBalance(0);
custCount++;
do
{
appQuit = false;
Console.Clear();
Console.Write("Enter UserName");
adminInput = Console.ReadLine();
if (adminInput == adminName)
{
Console.Write("Enter Admin Pin");
pinInput = Convert.ToInt32(Console.ReadLine());
if (pinInput != adminPin)
{
Console.WriteLine("You Have Entered Wrong Password");
Console.ReadKey();
continue;
}
else
{
do
{
Console.Clear();
adminQuit = false;
Console.WriteLine("\t\tPlease Select from the Menu");
Console.WriteLine("\t1. Add Customer to Application");
Console.WriteLine("\t2. Return Back to Login Screen");
Console.WriteLine("\t3. Exit the Application");
adminChoice = Convert.ToInt32(Console.ReadLine());
switch (adminChoice)
{
case 1:
//Add customer
break;
case 2:
adminQuit = true;
break;
case 3:
appQuit = true;
break;
default:
Console.WriteLine("Invalid Menu Selection");
return;
}} while (adminQuit == false && appQuit == false);
}}
else {
user = -1;
for (int i = 0; i < custCount; i++)
{
if (adminInput == myCustAcc[i].getCustomerUserName())
{
user = i;
break;} }
if (user == -1)
{
Console.WriteLine("User Does Not Exit !!! Please Try Again");
Console.ReadKey();
continue;
}
Console.Write("Enter User Pin");
if (Convert.ToInt32(Console.ReadLine()) != myCustAcc[user].getCustomerPin() )
{
Console.WriteLine("Invalid Pin");
Console.ReadKey();
continue;
}
do
{
Console.WriteLine("\t\t Welcome to Super Fast Banking Application");
Console.WriteLine("\n<<<Please Select Following Menus>>>");
Console.WriteLine("\t1> GetBalance");
Console.WriteLine("\t2> Deposit");
Console.WriteLine("\t3> Withdraw");
Console.WriteLine("\t4> Modify");
Console.WriteLine("\t5> Display");
Console.WriteLine("\t6> Exit");
input = Convert.ToInt32(Console.ReadLine());
switch (input)
{
case 1:
double balance;
balance = myCustAcc[user].getBalance();
Console.Write("Your Current Balance is {0:C} ",balance);
break;
case 2:
Console.Write("\nPlease enter Numbers to Deposit balance :");
myCustAcc[user].Customerdeposit();
Console.WriteLine("New Balance after Deposit is {0:C}", myCustAcc[user].getBalance());
break;
case 3:
Console.Write("\n Please enter Dollar Amount to Withdraw:");
myCustAcc[user].customerWithdraw();
Console.WriteLine("New Balance after Withdraw is {0:C}",myCustAcc[user].getBalance());
break;
case 4:
//modify
break;
case 5:
double newDisplay;
newDisplay = myCustAcc[user].getBalance();
Console.WriteLine("The Balance in your Account is {0:C}",newDisplay);
break;
case 6:
break;
default: Console.WriteLine("Exit the Application!!!");
break;
}
} while (appQuit == false);
}
Console.ReadKey();
} while (appQuit != true);
}}}
Some code from Account Class
public double getBalance()
{
return customerBalance;
}
public void Customerdeposit()
{
double deposit = Convert.ToDouble(Console.ReadLine());
if (deposit <= 0)
{
Console.WriteLine("\nCannot Deposit");
}
else
{
customerBalance = customerBalance + deposit;
}
}
public void customerWithdraw()
{
double withdraw = Convert.ToDouble(Console.ReadLine());
{
if (withdraw >= 0)
{
customerBalance = customerBalance - withdraw;
}
else
{
Console.WriteLine("There is not Sufficient fund in your account to withdraw");
} }}}
I try to write code for transaction class using the code below
But there are many errors at obj.Customerdeposit(amount); in both if condition and at Update(amount);
class Transaction
{
private int[] arr;
private int cntr;
Transaction()
{
arr = new int[5];
cntr = 0;
}
private void update(int amount)
{
arr[cntr] = amount;
cntr++;
}
public void credit(Account obj, int amount)
{
if(cntr!=5)
{
obj.Customerdeposit(amount);
return;
Update(amount);
}
else
{
Console.WriteLine("Transaction limit exceeded");
}}
public void debit(Account obj, int amount)
{
if(cntr!=5)
{
obj.customerWithdraw(amount);
return;
Update(-amount);
}
else
{
Console.WriteLine("Transaction limit exceeded");
}
}
}
}
You have specified everything from attributes to functions, just write the code.
Now this will be spoonfeeding but then too, your changes are wrong.
Account Class:
public double getBalance()
{
return customerBalance;
}
public bool Customerdeposit()
{
double deposit = Convert.ToDouble(Console.ReadLine());
if (deposit <= 0)
{
return false;
}
customerBalance = customerBalance + deposit;
return true;
}
public bool customerWithdraw()
{
double withdraw = Convert.ToDouble(Console.ReadLine());
{
if (withdraw <= 0 || customerBalance < withdraw )
{
return false;
}
customerBalance = customerBalance - withdraw;
return true;
}
}
}
Now your TransactionClass can be: (add other functionalities yourself)
class Transaction
{
private int[] arr;
private int cntr;
Transaction()
{
arr = new int[5];
cntr = 0;
}
private void update(int amount)
{
arr[cntr]=amount;
cntr++;
}
public void credit(Account obj, int amount)
{
if(cntr!=5)
{
if(obj.CustomerDeposit(amount))
Update(amount); //works only when true returned from above.
else
//print message
}
else
Console.WriteLine("Transaction limit exceeded");
}
public void debit(Account obj, int amount)
{
if(cntr!=5)
{
if(obj.CustomerWithdraw(amount))
Update(-amount);
else
//print any message
}
else
Console.WriteLine("Transaction limit exceeded");
}
}
Call will be made for each transaction:
Transaction trans= new Transaction();
trans.credit(myCustAcc[user],500);

Generic method named Max that takes 2 parameters and returns greater of 2 reference types

In C# Language Write a generic method named Max that takes 2 parameters and returns greater of 2 values. Apply constraint to support only reference types.Test it against Employee class which has salary as the property of type int.Max should compare two employee instances based on the salary and return employee instance which has greater salary.
This is what I have done How should i proceed further...?
using System;
using System.Collections.Generic;
using System.Text;
namespace Generic_Max_of_Salary
{
class Program
{
static void Main(string[] args)
{
runtest();
}
public static void runtest()
{
Test_Maximum(new Employee { Salary = 10000 }, new Employee { Salary = 20000 }, new Employee { Salary = 20000 }, 1);
Test_Maximum(new Employee { Salary = 30000 }, new Employee { Salary = 20000 }, new Employee { Salary = 30000 }, 2);
Test_Maximum(new Employee { Salary = 10000 }, new Employee { Salary = 10000 }, new Employee { Salary = 10000 }, 3);
}
public static void Test_Maximum(Employee emp1, Employee emp2, Employee obtained_answer, int testcase)
{
Employee expected_answer = Maximum<Employee>(emp1, emp2);
if (CompareTo(obtained_answer, expected_answer))
{
Console.WriteLine("Test " + testcase + " Passed");
}
else
{
Console.WriteLine("Test " + testcase + " Failed");
}
}
public static T Maximum<T>(T emp1, T emp2)
{
if (emp1.Salary >= emp2.Salary)
{
return emp1;
}
else
{
return emp2;
}
}
public static bool CompareTo(Employee obtained_answer, Employee expected_answer)
{
if (obtained_answer.Salary == expected_answer.Salary)
{
return true;
}
else
{
return false;
}
}
}
class Employee
{
public int Salary { get; set; }
}
}
That's because the compiler does not know that the open type T has a property called Salary. You can either add a constraint to T that it needs to be a derived class of Employee or you need to call the Maximum function with the salaries instead of the employee instances.
public static T Maximum<T>(T emp1, T emp2) where T: Employee
{
if (emp1.Salary >= emp2.Salary)
{
return emp1;
}
else
{
return emp2;
}
}
Just to elaborate on the question, a generic function only constraining on reference type like
static T Maximum<T>(T obj1, T obj2) where T : class
{
if (obj1 > obj2)
{
return obj1;
}
return obj2;
}
does not work as the > operator is not defined on T. Your best chance is to check if the input objects are IComparable or Employees:
static T Maximum<T>(T obj1, T obj2) where T : class
{
if (obj1 is Employee && obj2 is Employee)
{
if (((Employee)obj1).Salary > ((Employee)obj2).Salary)
{
return obj1;
}
return obj2;
}
if (obj1 is IComparable && obj2 is IComparable)
{
if (((IComparable)obj1).CompareTo(obj2) > 0)
{
return obj1;
}
return obj2;
}
throw new NotSupportedException("Cannot compare two reference types without knowledge of the type.");
}

What is the correct way to implement concurrency in wcf service?

I am trying understand concurrency in wcf and downloaded a sample code from here and done some changes for testing two way calls. To my surprise I could not see the effect of concurrency for two way calls (Although I can see concurrency for one way calls).
Is it the way WCF concurrency model works? (or)
Am I doing something terribly wrong?
This is the service code.
[ServiceContract]
public interface IHelloWorldService
{
[OperationContract(IsOneWay=true)]
void Call(string ClientName);
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class HelloWorldService : IHelloWorldService
{
public static int counter;
public HelloWorldService()
{
counter++;
}
public void Call(string ClientName)
{
Console.WriteLine("Instance:" + counter.ToString() + " Thread:" + Thread.CurrentThread.ManagedThreadId.ToString() + " Time:" + DateTime.Now.ToString() + "\n\n");
Thread.Sleep(5000);
}
public string GetData(int value)
{
Console.WriteLine("Instance:" + counter.ToString() + " Thread:" + Thread.CurrentThread.ManagedThreadId.ToString() + " Time:" + DateTime.Now.ToString() + "\n\n");
Thread.Sleep(5000);
return value.ToString();
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
Console.WriteLine("Instance:" + counter.ToString() + " Thread:" + Thread.CurrentThread.ManagedThreadId.ToString() + " Time:" + DateTime.Now.ToString() + "\n\n");
Thread.Sleep(5000);
return composite;
}
}
This is the service hosting code.
class Program
{
static void Main(string[] args)
{
//Create a URI to serve as the base address
//Uri httpUrl = new Uri("net.tcp://localhost:8001/HelloWorld");
Uri httpUrl = new Uri("http://localhost:8010/MyService/HelloWorld");
//Create ServiceHost
ServiceHost host
= new ServiceHost(typeof(ClassLibrary1.HelloWorldService), httpUrl);
//Add a service endpoint
host.AddServiceEndpoint(typeof(ClassLibrary1.IHelloWorldService)
, new WSHttpBinding(), "");
//Enable metadata exchange
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
host.Description.Behaviors.Add(smb);
ServiceThrottlingBehavior stb = new ServiceThrottlingBehavior();
stb.MaxConcurrentCalls = 100;
stb.MaxConcurrentInstances = 100;
stb.MaxConcurrentSessions = 100;
host.Description.Behaviors.Add(stb);
//Start the Service
host.Open();
Console.WriteLine("Service is host at " + DateTime.Now.ToString());
Console.WriteLine("Host is running... Press <Enter> key to stop");
Console.ReadLine();
}
}
This is the client code.
class Program
{
static int m_NumberOfWorkers = 10;
static readonly object m_Locker = new object();
static bool flag_GO = false;
static Stopwatch m_OverAllStopwatch = new Stopwatch();
static ConcurrentBag<Stopwatch> m_bagIndividualStopwatch = new ConcurrentBag<Stopwatch>();
static int m_CompletedWorkers = 0;
static ServiceReference1.HelloWorldServiceClient m_objProxy;
static int m_KindOfMethod;
static void Main(string[] args)
{
while(true)
{
try
{
flag_GO = false;
Console.WriteLine("Enter number of concurrent clients:");
m_NumberOfWorkers = Int32.Parse(Console.ReadLine());
Console.WriteLine("Kind of method (1: One way, 2: Two way 3: Two way using data contract):");
m_KindOfMethod = Int32.Parse(Console.ReadLine());
// Create Workers
List<Thread> lstThreads = new List<Thread>();
for (int i = 0; i < m_NumberOfWorkers; ++i)
{
lstThreads.Add(new Thread(WaitOnPulse));
}
// Start Workers
for (int i = 0; i < lstThreads.Count; ++i)
{
lstThreads[i].Start();
}
m_objProxy = new ServiceReference1.HelloWorldServiceClient();
m_OverAllStopwatch.Restart();
// Signal all workers
lock (m_Locker)
{
flag_GO = true;
Monitor.PulseAll(m_Locker);
}
// Wait all workers to finish
for (int i = 0; i < lstThreads.Count; ++i)
{
lstThreads[i].Join();
}
m_objProxy.Close();
m_objProxy = null;
}
catch
{
return;
}
}
}
private static void WaitOnPulse()
{
lock (m_Locker)
{
while (!flag_GO) Monitor.Wait(m_Locker);
}
TestWhatEverYouWant();
IamDone();
}
private static void TestWhatEverYouWant()
{
Stopwatch stopWatch = Stopwatch.StartNew();
//Thread.Sleep(1000);
switch (m_KindOfMethod)
{
case 1:
m_objProxy.Call(m_NumberOfWorkers.ToString() + "Client Calls");
break;
case 2:
m_objProxy.GetData(m_NumberOfWorkers);
break;
case 3:
ServiceReference1.CompositeType objData = new ServiceReference1.CompositeType();
m_objProxy.GetDataUsingDataContract(objData);
break;
}
stopWatch.Stop();
m_bagIndividualStopwatch.Add(stopWatch);
}
private static void IamDone()
{
Interlocked.Increment(ref m_CompletedWorkers);
// Summarize results if all workers are done
if (Interlocked.CompareExchange(ref m_CompletedWorkers, 0, m_NumberOfWorkers) == m_NumberOfWorkers)
{
m_OverAllStopwatch.Stop();
Console.WriteLine("OverAll Elapsed Time: {0}", m_OverAllStopwatch.ElapsedMilliseconds);
Stopwatch stopWatch;
while (m_bagIndividualStopwatch.TryTake(out stopWatch))
//foreach (Stopwatch stopWatch in m_bagIndividualStopwatch)
{
Console.WriteLine("Individual Elapsed Time: {0}", stopWatch.ElapsedMilliseconds);
}
}
}
}
This is the Cleint trace:
Enter number of concurrent clients:
8
Kind of method (1: One way, 2: Two way 3: Two way using data contract):
2
OverAll Elapsed Time: 42022
Individual Elapsed Time: 42021
Individual Elapsed Time: 37013
Individual Elapsed Time: 32008
Individual Elapsed Time: 26987
Individual Elapsed Time: 21981
Individual Elapsed Time: 16980
Individual Elapsed Time: 11968
Individual Elapsed Time: 6985
This is the server trace:
Instance:1 Thread:6 Time:12/17/2012 8:09:29 PM
Instance:1 Thread:5 Time:12/17/2012 8:09:34 PM
Instance:1 Thread:7 Time:12/17/2012 8:09:39 PM
Instance:1 Thread:7 Time:12/17/2012 8:09:44 PM
Instance:1 Thread:5 Time:12/17/2012 8:09:49 PM
Instance:1 Thread:7 Time:12/17/2012 8:09:54 PM
Instance:1 Thread:5 Time:12/17/2012 8:09:59 PM
Instance:1 Thread:7 Time:12/17/2012 8:10:04 PM
For these results you can clearly see that the requests were processed sequentially. Ideally I was expecting all the 8 concurrent requrest would finish in 5 sec. But it took around 42 sec to finish.
The problem in my code is the way the proxy is used. I have created just one proxy for all concurrent clients and all calls to the service were made through this proxy only. So, all these calls were getting queued in the channel. Creating one proxy for each client, the way one should simulate wcf load test, solved the problem.
I still think the problem is with settings; proxy and number of threads originating from each proxy, the link explains it well.
Also have a look at following link; may be test client can have a problem.
Seeking WCF Duplex "TwoWay" Subscribe+Callback Example

Resources