I have a small C# file that defines a SumCalculator class. It has a method CalculateSum(int totalSteps) that calculates the sum of numbers from 1 to totalSteps and raises a CalculationStep event returning arguments of LongOperationArgs class on each consecutive number. I want to create an instance of the Calculator class in my PowerShell 5.0 script and report the calculation progress using Write-Progress cmdlet. Here's the code:
$csharpSource = #'
using System;
namespace Test
{
public class LongOperationArgs : EventArgs {
public int TotalSteps { get; private set; }
public int CurrentStep { get; private set; }
public LongOperationArgs(int totalSteps, int currentStep) {
TotalSteps = totalSteps;
CurrentStep = currentStep;
}
}
public class SumCalculator {
public event EventHandler<LongOperationArgs> CalculationStep;
private void OnCalculationStep(LongOperationArgs e) {
EventHandler<LongOperationArgs> handler = CalculationStep;
if (handler != null) {
handler(this, e);
}
}
public int CalculateSum(int totalSteps) {
var sum = 0;
for(var i = 1; i <= totalSteps; i++) {
sum += i;
OnCalculationStep(new LongOperationArgs(totalSteps, i));
}
return sum;
}
}
}
'#
Add-Type -TypeDefinition "$csharpSource"
$calculator = New-Object Test.SumCalculator
$action =
{
$jobId = 1;
$jobActivity = "Calculating...";
if ($EventArgs.CurrentStep -eq $EventArgs.TotalSteps)
{
Write-Progress -Id $jobId -Activity $jobActivity -Completed;
}
else
{
Write-Progress -Id $jobId -Activity $jobActivity -Status "Step $($EventArgs.CurrentStep) of $($EventArgs.TotalSteps)" -PercentComplete ($EventArgs.CurrentStep / $EventArgs.TotalSteps * 100);
}
}
$bar = Register-ObjectEvent -InputObject $calculator -EventName "CalculationStep" -Action $action
$calculator.CalculateSum(100);
My problem is that Powershell runs CalculateSum() and Write-Progress in the same thread. So first CalculateSum() runs to completion, and only then Write-Progress starts reporting progress. My first response was to change the last line of my script from
$calculator.CalculateSum(100);
to
$job = Start-Job { $calculator.CalculateSum(100); }
but that caused the progress to stop being reported (Write-Progress likely wants events from $calculator to be thrown in the same thread). Is there any way to make Write-Progress respond to $calculator events when calculation is done in a different thread?
Related
I'm trying to load information with worker and using reportprogress to update progress bar until finshing, but the worker stop working and doesn't finish the for loop or continue after several minutes. I don't know what's the problem and I tried every post here I can find related to this problem and didn't get anything. I hope I can finally get an answer posting my problem here.
Here's the relevant code:
public class Class1
{
public BackgroundWorker unit_read_data_setting_Worker;
public Class1()
{
unit_read_data_setting_Worker = new BackgroundWorker();
unit_read_data_setting_Worker.WorkerReportsProgress = true;
unit_read_data_setting_Worker.WorkerSupportsCancellation = false;
unit_read_data_setting_Worker.DoWork += new DoWorkEventHandler(unit_read_data_setting);
unit_read_data_setting_Worker.ProgressChanged += new ProgressChangedEventHandler(_update_progress);
unit_read_data_setting_Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Completed);
}
public void unit_read_data_setting(object sender = null, DoWorkEventArgs e = null)
{
lock (FamilyTreeViewModel.Lock_ParameterList)
{
ObservableCollection<Parameter_UC_ViewModel> _internal_parameter_list =
FamilyTreeViewModel.GetInstance.ParameterList;
if (FamilyTreeViewModel.GetInstance.SelectedUnitSetting != null)
{
if (_internal_parameter_list.Count > 0)
{
for (int i = 0; i < _internal_parameter_list.Count; i++)
{
int startValue = i * 100 / _internal_parameter_list.Count;
unit_read_data_setting_Worker.ReportProgress(startValue);
// do stuff related to the index
// when progress_bar at 76 value, the loop stoppes and cotinue after a minute
}
}
}
}
}
private void _update_progress(object sender, ProgressChangedEventArgs e)
{
FamilyTreeViewModel.GetInstance.Unit_read_data_setting_progress_bar = e.ProgressPercentage;
}
private void Completed(object sender, RunWorkerCompletedEventArgs e)
{
// never gets here but there's no error
}
}
I have this code working well synchronously with powershell.Invoke() however with powershell.BeginInvoke() I am not able to capture the output. To use the below code you'll need to populate the $servers variable and it should run otherwise.
I tried to capture the output by adding each thread to the $threads variable while using EndInvoke() and I am able to see the thread handle and the iscompleted value, however I can't figure out where the value I am returning with the return portion of each function is stored.
The first block is the output I see, showing false for one async being finished until it finishes and then all thread handles show true.
Thanks!
8804 is True
16420 is True
13352 is True
11184 is True
3872 is True
8288 is True
17296 is False
20816 is True
11628 is True
17688 is True
12856 is True
19400 is True
8804 is True
16420 is True
13352 is True
11184 is True
3872 is True
8288 is True
17296 is True
20816 is True
11628 is True
17688 is True
12856 is True
19400 is True
Thread count: 12
Time elapsed: 3
cls;
$stopwatch = [system.diagnostics.stopwatch]::StartNew();
#region Runspace Pool
[runspacefactory]::CreateRunspacePool() | Out-Null;
$SessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault();
$RunspacePool = [runspacefactory]::CreateRunspacePool(
1, #Min Runspaces
16 #Max Runspaces
);
$RunspacePool.Open();
#endregion Runspace pool
$threads = New-Object System.Collections.ArrayList;
$servers = #("goodServer1", "goodServer2", "badServer1", "goodServer3");
foreach ($server in $servers)
{
$PowerShell = [powershell]::Create();
$PowerShell.RunspacePool = $RunspacePool;
[void]$PowerShell.AddScript({
Param ($server, $portNumber)
[pscustomobject]#{
server = $server
portNumber = $portNumber
} | Out-Null
Function testPort ($server, $portNumber)
{
$testPort = New-Object System.Net.Sockets.TCPClient # -ArgumentList $server, 3389;
$testPort.SendTimeout = 3;
try
{
$testPort.Connect($server, $portNumber);
}
catch
{
#do nothing;
}
$result = $testPort.Connected;
$testPort.Close();
$dateTime = ([DateTime]::Now.ToString());
return "$server|testPort|$result|$dateTime"; # server | function | result | DateTime
}
testPort -server $server -portNumber $portNumber;
}) # end of add script
$portNumber = "3389";
$PowerShell.AddParameter('server', $server).AddParameter('portNumber', $portNumber) | Out-Null;
$returnVal = $PowerShell.BeginInvoke();
$temp = "" | Select PowerShell,returnVal;
$temp.PowerShell = $PowerShell;
$temp.returnVal = $returnVal;
$threads.Add($Temp) | Out-Null;
$PowerShell = [powershell]::Create();
$PowerShell.RunspacePool = $RunspacePool;
[void]$PowerShell.AddScript({
Param ($server, $shareName, $timeOutInMs)
[pscustomobject]#{
server = $server
shareName = $shareName
timeOutInMs = $timeOutInMs
} | Out-Null
Function testShare ($server, $shareName, $timeOutInMs)
{
$cSharp =
#'
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace cSharp7
{
public class cSharpClass
{
public bool verifyDirectoryExists(string uri, int timeoutInMs)
{
var task = new Task<bool>(() =>
{
var dir = new DirectoryInfo(uri);
return dir.Exists;
});
task.Start();
return task.Wait(timeoutInMs) && task.Result;
}
public bool verifyFileExists(string uri, int timeoutInMs)
{
var task = new Task<bool>(() =>
{
var fi = new FileInfo(uri);
return fi.Exists;
});
task.Start();
return task.Wait(timeoutInMs) && task.Result;
}
}
}
'#
$assemblies = ("System", "System.Collections", "System.ComponentModel", "System.Data", "System.Drawing", "System.Linq", "System.Threading.Tasks", "System.Windows.Forms", "System.Management.Automation", "System.Security", "System.Threading", "System.Collections.Concurrent", "System.Security.Principal", "System.Management", "System.IO", "System.Collections");
Add-Type -TypeDefinition $cSharp -ReferencedAssemblies $assemblies -Language CSharp;
$directoryExists = New-Object CSharp7.cSharpClass;
$path = "\\" + $server + "\" + $shareName;
try
{
$result = $directoryExists.verifyDirectoryExists($path, $timeOutInMs); # has a 2 minute timeout period, needs an asynchronous thread with a timeout period
#Write-Host $result;
}
catch
{
# do nothing
}
$dateTime = ([DateTime]::Now.ToString());
return "$server|testShare|$result|$dateTime"; # server | function | result | DateTime
}
testShare -server $server -shareName $shareName -timeOutInMs $timeOutInMs;
}) # end of add script
$shareName = "c$";
$timeOutInMs = "3000";
$PowerShell.AddParameter('server', $server).AddParameter('shareName', $shareName).AddParameter('timeOutInMs', $timeOutInMs) | Out-Null;
$returnVal = $PowerShell.BeginInvoke();
$temp = "" | Select PowerShell,returnVal;
$temp.PowerShell = $PowerShell;
$temp.returnVal = $returnVal;
$threads.Add($Temp) | Out-Null;
$PowerShell = [powershell]::Create();
$PowerShell.RunspacePool = $RunspacePool;
[void]$PowerShell.AddScript({
Param ($server, $pingCount)
[pscustomobject]#{
server = $server
pingCount = $pingCount
} | Out-Null
Function testPing ($server, $pingCount)
{
try
{
$result = Test-Connection $server -Count $pingCount -Quiet;
}
catch
{
# do nothing
}
$dateTime = ([DateTime]::Now.ToString());
return "$server|testPing|$result|$dateTime"; # server | function | result | DateTime
}
testPing -server $server -pingCount $pingCount;
}) # end of add script
$pingCount = "1";
$PowerShell.AddParameter('server', $server).AddParameter('pingCount', $pingCount) | Out-Null;
$returnVal = $PowerShell.BeginInvoke();
$temp = "" | Select PowerShell,returnVal;
$temp.PowerShell = $PowerShell;
$temp.returnVal = $returnVal;
$threads.Add($Temp) | Out-Null;
}
$completed = $false;
while ($completed -eq $false)
{
$completed = $true;
foreach ($thread in $threads)
{
$endInvoke = $thread.PowerShell.EndInvoke($thread.returnVal);
$endInvoke;
$threadHandle = $thread.returnVal.AsyncWaitHandle.Handle;
$threadIsCompleted = $thread.returnVal.IsCompleted;
#Write-Host "$threadHandle is $threadIsCompleted";
if ($threadIsCompleted -eq $false)
{
$completed = $false;
}
}
Write-Host "";
sleep -Milliseconds 500;
}
foreach ($thread in $threads)
{
$thread.PowerShell.Dispose();
}
$stopwatch.Stop();
Write-Host "";
Write-Host "Thread count:" $threads.Count;
Write-Host "Time elapsed:" $stopwatch.Elapsed.Seconds;
Here is how you capture the return value data. You define the custom object $temp with 2 properties names, in thise case Powershell and returnVal. Then you add them to an array list. After the async BeginInvoke is completed you can call EndInvoke against the asyncResult by doing this $endInvoke = $thread.PowerShell.EndInvoke($thread.returnVal); and parse it however you want.
This has to be the most complicated script I've ever written with a runspace pool, runspaces, asynchronous returns, functions being passed and even some c# mixed in. Hopefully others can draw from parts or all of this.
$returnVal = $PowerShell.BeginInvoke();
$temp = "" | Select PowerShell,returnVal;
$temp.PowerShell = $PowerShell;
$temp.returnVal = $returnVal;
$threads.Add($Temp) | Out-Null;
$completed = $false;
while ($completed -eq $false)
{
$completed = $true;
foreach ($thread in $threads)
{
$endInvoke = $thread.PowerShell.EndInvoke($thread.returnVal);
$endInvoke;
$threadHandle = $thread.returnVal.AsyncWaitHandle.Handle;
$threadIsCompleted = $thread.returnVal.IsCompleted;
#Write-Host "$threadHandle is $threadIsCompleted";
if ($threadIsCompleted -eq $false)
{
$completed = $false;
}
}
Write-Host "";
sleep -Milliseconds 500;
}
foreach ($thread in $threads)
{
$thread.PowerShell.Dispose();
}
I have this code, in file that have the name dao.abstract.class.php, but I am getting this error when I surf the site, and admin panel. Strict Standards: Static function DAO::makeItem() should not be abstract in dao.abstract.class.php on line 15
<?php
abstract class DAO
{
protected $m_sql;
protected $m_sqlId = -1;
protected $m_orderBy;
protected $m_orderByField;
protected $m_orderByType;
**abstract public function selectFromId($iditem);
abstract public function delete($iditem);
abstract public function save($object);
abstract static function makeItem($resultRow);
abstract protected function createSql();**
protected function __construct($sql, $sortField, $sortType)
{
$this->m_sql = $sql;
$this->m_orderBy = array($sortField => $sortType);
$this->m_orderByField = $sortField;
$this->m_orderByType = $sortType;
}
public function setOrderBy($order_by, $field, $type)
{
$this->m_orderBy = $order_by;
$this->m_orderByField = $field;
$this->m_orderByType = $type;
}
public function getOrderBy()
{
return $this->m_orderBy;
}
public function getOrderByField()
{
return $this->m_orderByField;
}
public function getOrderByType()
{
return $this->m_orderByType;
}
protected function executeQuery($objectArray = true, $renew = false)
{
if ($result = mysql_query($this->m_sql->getCommand($this->m_sqlId)))
{
if($objectArray == true)
{
$item = array();
while($row = mysql_fetch_assoc($result))
$item[] = $this->makeComplexItem($row);
}
elseif($row = mysql_fetch_assoc($result))
$item = $this->makeComplexItem($row);
else
$item = null;
}
else
Die(mysql_error().'<br/>'.$this->m_sql->getCommand());
mysql_free_result($result);
if($renew == true)
$this->m_sqlId = -1;
return $item;
}
protected function executeOneFieldQuery($array = true)
{
if ($result = mysql_query($this->m_sql->getCommand()))
{
if($array == true)
{
$item = array();
while($row = mysql_fetch_row($result))
$item[] = $row[0];
}
elseif($row = mysql_fetch_row($result))
$item = $row[0];
else
$item = null;
mysql_free_result($result);
return $item;
}
else
Die(mysql_error());
}
protected function executeSave($itemId)
{
if($itemId == -1)
$this->m_sql->setExecMode(Clarity::EXEC_INSERT);
else
$this->m_sql->setExecMode(Clarity::EXEC_UPDATE);
if ($itemId == -1 AND mysql_query($this->m_sql->getCommand()))
return mysql_insert_id();
elseif($itemId > 0 AND mysql_query($this->m_sql->getCommand()))
return $itemId;
else
Die(mysql_error().'<br/>'.$this->m_sql->getCommand());
}
protected function executeDelete()
{
$this->m_sql->setExecMode(Clarity::EXEC_DELETE);
if(mysql_query($this->m_sql->getCommand()))
return mysql_affected_rows();
else
die(mysql_error());
}
}
?>
You can move this declaration to an interface.
Like this:
interface myInterface
{
static function makeItem($resultRow);
}
abstract class DAO implements myInterface
{
[...]
}
A newbie, please excuse the terms and explanation.
I have a program that accepts arguments which are in seconds. This in turn runs a timer that shows on the form. I want to give the user the ability to pause the timer for a set amount of time. I am having difficulty in trying to add time after the user Clicks the button as the method that runs the timer and countdown I have a method that gets the parameters of the argument.
I would like to maybe just get the parameters/arguments globally and then use them in all the different methods or threads. I am trying to do this in c# and wpf.
Code below:
public partial class MainWindow : Window
{
//int TimeOutPeriod = Int32.Parse("3600");
//private Timer timer;
System.Timers.Timer timer = new System.Timers.Timer();
public MainWindow()
{
InitializeComponent();
//timer = new Timer(1000);
timer = new System.Timers.Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
string[] param = Environment.GetCommandLineArgs();
int TimeOutPeriod = Int32.Parse(param[1]);
ProgressBar1.Maximum = TimeOutPeriod;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
string [] param = Environment.GetCommandLineArgs();
int TimeOutPeriod = Int32.Parse(param[1]);
int InYourFaceDisplay = Int32.Parse(param[2]);
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)(() =>
{
if (ProgressBar1.Value < TimeOutPeriod)
{
ProgressBar1.Value += 1;
RebootCDown.Content = "Machine will reboot in : " + (TimeOutPeriod - ProgressBar1.Value) + " Secs";
if ((TimeOutPeriod - ProgressBar1.Value) < InYourFaceDisplay)
{
this.Activate();
}
}
else
{
ShutDownWindows("0");
timer.Stop();
this.Close();
}
}));
}
private void SnoozeNow_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
System.Windows.Forms.NotifyIcon ni = new System.Windows.Forms.NotifyIcon();
ShowInTaskbar = false;
ni.Icon = new System.Drawing.Icon("C:\\temp\\RebootIco.ico");
ni.Visible = true;
ShowInTaskbar = false;
ni.ShowBalloonTip(5000, "Test App", "Notify icon is working! Right click to access the context menu.", System.Windows.Forms.ToolTipIcon.Info);
Task.Delay(10000);
ShowInTaskbar = true;
}
}
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