C#如何同时多次调用单个方法 [英] C# How to Call single method multiple times simultaneously

查看:119
本文介绍了C#如何同时多次调用单个方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个调用Web服务的方法。

 function  void  SendAsync( object 输入)
{
// 日志发送到WebService之前的时间(T1)
......调用WebMethod ....
// 发送到WebService后的日志时间(T2)
}





I想要运行循环并使用不同的输入数据调用Web方法。在没有等待响应的情况下,我希望继续调用Web方法。

  for  int  i =  1 ; i< =  100 ; i ++ )
{
// 调用异步方法之前的日志时间(T0)

// TRIAL 1
ThreadPool.QueueUserWorkItem( new WaitCallback(t.SendAsync),i.ToString());

// 试用2
new 任务(()= > {SendAsync(i.ToString());})。Start();

// TRIAL 3
Task.Factory.StartNew( ()= > SendAsync(i.ToString()));

// TRIAL 4
AsyncTask_Delegate adel = ;
adel = new AsyncTask_Delegate(SendAsync);
IAsyncResult R = null ;
R = adel.BeginInvoke(i.ToString(), null null ); // 调用方法
}



我想将此函数称为异步调用。我已尝试过如上所述的各种方法。



T0和T1之间的时间相当长(即使在15-40秒内)。下一个方法调用在循环中发生,但实际的Web调用方法正在延迟。该方法不是同时运行的。我甚至把SendAsync方法放在不同的类中并调用方法仍然是相同的结果.....



------------ -------------------------------------------------- ------------------







在这个问题上添加更多信息是我在每个循环中创建一个输入字符串并将其发送到一个函数进行处理。



而不是调用Web方法甚至当我们调用Normal简单方法时,T0和T1之间的差异很大。



同样的函数在异步模式下运行但根本无法同时运行或启动。



我试图创建一个像var tmp = i;这样的副本。在调用之前,但是延迟仍然存在。

解决方案

我认为输入字符串的构建是这里的罪魁祸首(或者可能是代码中不可见的其他东西)你提供的样本)。



如果你产生了一个任务(无论是任务,还是线程池工作人员甚至专用线程)这样做和开始执行之间的时间应该很小。



拿这个示例程序;

 使用系统; 
使用 System.Threading;
使用 System.Threading.Tasks;

命名空间 ConsoleApplication1 {
class 计划{
static void 日志( string message){
Console.WriteLine( {0:00} @ {1}; {2},Thread.CurrentThread.ManagedThreadId,DateTime.Now,message);
}

静态 void SendAsync( object input){
Log( String .Format( - > SendAsync; {0},输入));
// Thread.Sleep(500);
Log( < - SendAsync);
}

静态 void Invoke_1( int index){
ThreadPool.QueueUserWorkItem(SendAsync,index);
}

静态 void Invoke_2( int index){
new 任务(()= > SendAsync(index))。Start();
}

静态 void Invoke_3( int index){
Task.Factory.StartNew(()= > SendAsync(index));
}

静态 void Main(){
const int iterations = 100 ;

for var i = 0 ; i < 迭代; ++ i){
var index = i;
Log( String .Format( Loop迭代{0},索引));
// Invoke_1(index);
Invoke_2(index);
// Invoke_3(index);
}

Log( 全部调度,按任意键终止......);
Console.ReadKey();
}
}
}



它生成的输出看起来像这样;

 09 @ 26-08-2014 09:28:04;循环迭代0 
09 @ 26-08-2014 09:28:04;循环迭代1
09 @ 26-08-2014 09:28:04;循环迭代2
09 @ 26-08-2014 09:28:04;循环迭代3
11 @ 26-08-2014 09:28:04; - > SendAsync; 0
11 @ 26-08-2014 09:28:04; < - SendAsync
10 @ 26-08-2014 09:28:04; - > SendAsync; 1
10 @ 26-08-2014 09:28:04; < - SendAsync
09 @ 26-08-2014 09:28:04;循环迭代4
09 @ 26-08-2014 09:28:04;循环迭代5
09 @ 26-08-2014 09:28:04;循环迭代6
09 @ 26-08-2014 09:28:04;循环迭代7
09 @ 26-08-2014 09:28:04;循环迭代8
09 @ 26-08-2014 09:28:04;循环迭代9
09 @ 26-08-2014 09:28:04;循环迭代10
09 @ 26-08-2014 09:28:04;循环迭代11
09 @ 26-08-2014 09:28:04;循环迭代12
09 @ 26-08-2014 09:28:04;循环迭代13
09 @ 26-08-2014 09:28:04;循环迭代14
09 @ 26-08-2014 09:28:04;循环迭代15
09 @ 26-08-2014 09:28:04;循环迭代16
09 @ 26-08-2014 09:28:04;循环迭代17
09 @ 26-08-2014 09:28:04;循环迭代18
09 @ 26-08-2014 09:28:04;循环迭代19
09 @ 26-08-2014 09:28:04;循环迭代20
09 @ 26-08-2014 09:28:04;循环迭代21
09 @ 26-08-2014 09:28:04;循环迭代22
09 @ 26-08-2014 09:28:04;循环迭代23
09 @ 26-08-2014 09:28:04;循环迭代24
09 @ 26-08-2014 09:28:04;循环迭代25
09 @ 26-08-2014 09:28:04;循环迭代26
09 @ 26-08-2014 09:28:04;循环迭代27
09 @ 26-08-2014 09:28:04;循环迭代28
09 @ 26-08-2014 09:28:04;循环迭代29
09 @ 26-08-2014 09:28:04;循环迭代30
09 @ 26-08-2014 09:28:04;循环迭代31
09 @ 26-08-2014 09:28:04;循环迭代32
09 @ 26-08-2014 09:28:04;循环迭代33
09 @ 26-08-2014 09:28:04;循环迭代34
09 @ 26-08-2014 09:28:04;循环迭代35
09 @ 26-08-2014 09:28:04;循环迭代36
09 @ 26-08-2014 09:28:04;循环迭代37
09 @ 26-08-2014 09:28:04;循环迭代38
09 @ 26-08-2014 09:28:04;循环迭代39
09 @ 26-08-2014 09:28:04;循环迭代40
09 @ 26-08-2014 09:28:04;循环迭代41
09 @ 26-08-2014 09:28:04;循环迭代42
09 @ 26-08-2014 09:28:04;循环迭代43
09 @ 26-08-2014 09:28:04;循环迭代44
09 @ 26-08-2014 09:28:04;循环迭代45
10 @ 26-08-2014 09:28:04; - > SendAsync; 2
10 @ 26-08-2014 09:28:04; < - SendAsync
09 @ 26-08-2014 09:28:04;循环迭代46



你可以看到之间的增量时间

 09 @ 26-08-2014 09:28 :04;循环迭代0 





 11 @ 26-08-2014 09:28:04; - > SendAsync; 0 



在亚秒级范围内。



什么减慢你的应用程序是非常繁重的参与创建输入字符串或可能进行一些锁定,而不是你产生线程的方式。



希望这会有所帮助,

Fredrik


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.....

--------------------------------------------------------------------------------



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.

解决方案

I think the building of the input string is the culprit here (or possibly some other thing that's not visible in the code sample you've provided).

If you spawn of a task (be it a Task, thread pool worker or even a dedicated thread) the time between doing so and it starting to execute should be small.

Take this example program;

using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1 {
    class Program {
        static void Log(string message) {
            Console.WriteLine("{0:00} @ {1}; {2}", Thread.CurrentThread.ManagedThreadId, DateTime.Now, message);
        }

        static void SendAsync(object input) {
            Log(String.Format("--> SendAsync; {0}", input));
            //Thread.Sleep(500);
            Log("<-- SendAsync");
        }

        static void Invoke_1(int index) {
            ThreadPool.QueueUserWorkItem(SendAsync, index);
        }

        static void Invoke_2(int index) {
            new Task(() => SendAsync(index)).Start();
        }

        static void Invoke_3(int index) {
            Task.Factory.StartNew(() => SendAsync(index));
        }

        static void Main() {
            const int iterations = 100;

            for (var i = 0; i < iterations; ++i) {
                var index = i;
                Log(String.Format("Loop iteration {0}", index));
                //Invoke_1(index);
                Invoke_2(index);
                //Invoke_3(index);
            }

            Log("All dispatched, press any key to terminate...");
            Console.ReadKey();
        }
    }
}


It generates output that looks something like this;

09 @ 26-08-2014 09:28:04; Loop iteration 0
09 @ 26-08-2014 09:28:04; Loop iteration 1
09 @ 26-08-2014 09:28:04; Loop iteration 2
09 @ 26-08-2014 09:28:04; Loop iteration 3
11 @ 26-08-2014 09:28:04; --> SendAsync; 0
11 @ 26-08-2014 09:28:04; <-- SendAsync
10 @ 26-08-2014 09:28:04; --> SendAsync; 1
10 @ 26-08-2014 09:28:04; <-- SendAsync
09 @ 26-08-2014 09:28:04; Loop iteration 4
09 @ 26-08-2014 09:28:04; Loop iteration 5
09 @ 26-08-2014 09:28:04; Loop iteration 6
09 @ 26-08-2014 09:28:04; Loop iteration 7
09 @ 26-08-2014 09:28:04; Loop iteration 8
09 @ 26-08-2014 09:28:04; Loop iteration 9
09 @ 26-08-2014 09:28:04; Loop iteration 10
09 @ 26-08-2014 09:28:04; Loop iteration 11
09 @ 26-08-2014 09:28:04; Loop iteration 12
09 @ 26-08-2014 09:28:04; Loop iteration 13
09 @ 26-08-2014 09:28:04; Loop iteration 14
09 @ 26-08-2014 09:28:04; Loop iteration 15
09 @ 26-08-2014 09:28:04; Loop iteration 16
09 @ 26-08-2014 09:28:04; Loop iteration 17
09 @ 26-08-2014 09:28:04; Loop iteration 18
09 @ 26-08-2014 09:28:04; Loop iteration 19
09 @ 26-08-2014 09:28:04; Loop iteration 20
09 @ 26-08-2014 09:28:04; Loop iteration 21
09 @ 26-08-2014 09:28:04; Loop iteration 22
09 @ 26-08-2014 09:28:04; Loop iteration 23
09 @ 26-08-2014 09:28:04; Loop iteration 24
09 @ 26-08-2014 09:28:04; Loop iteration 25
09 @ 26-08-2014 09:28:04; Loop iteration 26
09 @ 26-08-2014 09:28:04; Loop iteration 27
09 @ 26-08-2014 09:28:04; Loop iteration 28
09 @ 26-08-2014 09:28:04; Loop iteration 29
09 @ 26-08-2014 09:28:04; Loop iteration 30
09 @ 26-08-2014 09:28:04; Loop iteration 31
09 @ 26-08-2014 09:28:04; Loop iteration 32
09 @ 26-08-2014 09:28:04; Loop iteration 33
09 @ 26-08-2014 09:28:04; Loop iteration 34
09 @ 26-08-2014 09:28:04; Loop iteration 35
09 @ 26-08-2014 09:28:04; Loop iteration 36
09 @ 26-08-2014 09:28:04; Loop iteration 37
09 @ 26-08-2014 09:28:04; Loop iteration 38
09 @ 26-08-2014 09:28:04; Loop iteration 39
09 @ 26-08-2014 09:28:04; Loop iteration 40
09 @ 26-08-2014 09:28:04; Loop iteration 41
09 @ 26-08-2014 09:28:04; Loop iteration 42
09 @ 26-08-2014 09:28:04; Loop iteration 43
09 @ 26-08-2014 09:28:04; Loop iteration 44
09 @ 26-08-2014 09:28:04; Loop iteration 45
10 @ 26-08-2014 09:28:04; --> SendAsync; 2
10 @ 26-08-2014 09:28:04; <-- SendAsync
09 @ 26-08-2014 09:28:04; Loop iteration 46


As you can see the delta time between

09 @ 26-08-2014 09:28:04; Loop iteration 0


and

11 @ 26-08-2014 09:28:04; --> SendAsync; 0


is in the sub-second range.

What's slowing your app down is either very heavy lifting involved in creating the input-string or possibly some locking going on, not the way you spawn threads.

Hope this helps,
Fredrik


这篇关于C#如何同时多次调用单个方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆