在BeginInvoke()中调用异步方法会产生一个新的'线?

时间:2014-08-08 22:29:31

标签: c# multithreading asynchronous begininvoke

'新'来自线程池的含义。

鉴于以下示例,我的假设是:

  1. 主要方法在一个线程(例如,线程1)上执行
  2. BeginInvoke使用池中的可用线程来执行AsyncDemo.TestMethod(线程2)
  3. 异步方法调用,例如WebClient.UploadStringAsync使用另一个可用线程(线程3)
  4. 第三个问题源于我的问题,WebClient.UploadStringAsync的定义:将指定的字符串上传到指定的资源。这些方法不会阻塞调用线程。

    这是否意味着它使用池中的另一个可用线程?这是一种不明智的技术(异步中的异步)吗?

    我的最终目标是异步发布一些数据(发射并忘记),并且之前使用的是UploadStringAsync。现在我决定用BeginInvoke封装周围的代码,但是想一想我是否必须将UploadStringAsync更改为同步方法(UploadString())。

    感谢您的帮助!

    public class AsyncMain 
    {
        // The delegate will be called asynchronously.
        public delegate string AsyncMethodCaller(out int threadId);
    
        public static void Main() 
        {       
            // The asynchronous method puts the thread id here.
            int threadId;       
    
            //Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(AsyncDemo.TestMethod);
    
            // Initiate the asychronous call.
            IAsyncResult result = caller.BeginInvoke(out threadId, null, null);     
    
            Console.WriteLine("In AsyncMain.Main() Thread {0} does some work.", Thread.CurrentThread.ManagedThreadId);
    
            // Call EndInvoke to wait for the asynchronous call to complete,
            // and to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);
    
            Console.WriteLine("The async call executed on thread {0}, has responded with \"{1}\". The result is {2}", threadId, returnValue, result);
        }
    }
    
    
    public class AsyncDemo 
    {   
        // The method to be executed asynchronously.
        public static string TestMethod(out int threadId) 
        {
            //get threadId, assign it.
            threadId = Thread.CurrentThread.ManagedThreadId;
            Console.WriteLine("TestMethod() begins at thread {0}", threadId);
    
            //Do work
    
            //Do ASYNC Method such as: WebClient.UploadStringAsync
    
            return String.Format("I'm finished my work.");
        }
    }
    

1 个答案:

答案 0 :(得分:3)

  

这是否意味着它使用池中的另一个可用线程?

简短回答:是的。

  1. 根据UploadStringAsync的文档:

      

    使用从线程池自动分配的线程资源异步发送字符串。

  2. 和BeginInvoke uses a thread from the thread pool完成异步行为。

  3.   

    这是一种不明智的技术(异步中的异步)吗?

    如果您需要在两个级别都进行异步行为,那么您可以执行您必须执行的操作。但总的来说,最好的建议是编写最简单的代码,这样就可以使用,所以如果只能通过一个间接层实现,我就会说它。

    不幸的是,您无法升级到较新版本的.NET,因为使用较新版本,您可以更简单地使用任务完成同样的事情:

    public static void Main() 
    {       
        Task<string> task = AsyncDemo.TestMethod();
    
        Console.WriteLine("In AsyncMain.Main() Thread {0} does some work.", Thread.CurrentThread.ManagedThreadId);
    
        string returnValue = task.Result; // This will cause the main thread to block until the result returns.
    
        Console.WriteLine("The async call executed on thread {0}, has responded with \"{1}\". The result is {2}", threadId, returnValue, result);
    }
    
    
    
    public class AsyncDemo 
    {   
        // The method to be executed asynchronously.
        public async static Task<string> TestMethod() 
        {
            Console.WriteLine("TestMethod() begins");
    
            //Do work
    
            await new WebClient().UploadStringTaskAsync("...", "...");
    
            return String.Format("I'm finished my work.");
        }
    }