Reputation: 1
I have a Method which calls a Web Service.
function void SendAsync( object input )
{
// Log Time Before Send to WebService (T1)
...... Call WebMethod ....
// Log Time After Send to WebService (T2)
}
I want to run a loop and call the Web method with different Input data. Without waiting for the response I want to keep on calling the Web Method.
for ( int i=1;i<=100;i++ )
{
//LOG TIME BEFORE Calling Async Method (T0)
//TRIAL 1
ThreadPool.QueueUserWorkItem(new WaitCallback(t.SendAsync), i.ToString());
//TRIAL 2
new Task(() => { SendAsync(i.ToString()); }).Start();
//TRIAL 3
Task.Factory.StartNew(() => SendAsync(i.ToString()));
//TRIAL 4
AsyncTask_Delegate adel = null;
adel = new AsyncTask_Delegate(SendAsync);
IAsyncResult R = null;
R = adel.BeginInvoke(i.ToString(), null, null); //invoking the method
}
I want to call this function as Async call. I have tried various approaches as mentioned above.
The time between T0 and T1 is quite substantial (Even in 15-40 Seconds). Next Method call is happening in the loop, but the actual Call to the Web method is getting delayed. The method is not running concurrently. I even put the SendAsync method in different class and call the method still the same result.....
Thank you all for your responses.
Adding more light on the problem is that I am creating an input string during each loop and sending it to a function for processing.
Also instead of Calling a Web Method even when we call a normal simple method, the difference between T0 and T1 is large.
The same function is running in Async mode but simply not able to run or start simultaneously.
I have tried to create a copy like "var tmp=i;" before calling, but delay is still present.
Upvotes: 0
Views: 10589
Reputation: 1500415
I suspect it is running concurrently - but that the degree of concurrency is being limited by the HTTP connection pool.
You might to change ServicePointManager.DefaultConnectionLimit
or set it in your app.config with the <connectionManagement>
element.
Additionally, note that these lines are suspect:
new Task(() => { SendAsync(i.ToString()); }).Start();
Task.Factory.StartNew(() => SendAsync(i.ToString()));
In both cases you're capturing i
, which is being update by the main thread. You need to capture a copy of the value of i
for that iteration:
int x = i;
new Task(() => { SendAsync(x.ToString()); }).Start();
Task.Factory.StartNew(() => SendAsync(x.ToString()));
Otherwise you may well see SendAsync("2")
twice and no call to SendAsync("1")
for example.
Upvotes: 5
Reputation: 9859
This works for me and runs async:
void Main()
{
for ( int i=1;i<=100;i++ )
{
var tmp = i; // this line is needed, you might get the same value for variable i for several calls otherwize!
Task.Run(() => { SendAsync(tmp.ToString()); });
}
}
Upvotes: 0
Reputation: 24395
I'm not an expert on async, but i think you want something like this:
var tasks = new List<Task>();
for(int i = 0; i< 100; i ++)
tasks.Add(Task<int>.Factory.StartNew(() => SendAsync(i), i));
Task.WaitAll(tasks);
More info: http://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx
Upvotes: 0