首页 文章

在BeginInvoke()中调用异步方法会产生一个'new'线程吗?

提问于
浏览
4

线程池中的“新”含义 .

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

  • 主方法在一个线程上执行(例如,线程1)

  • BeginInvoke使用池中的可用线程来执行AsyncDemo.TestMethod(线程2)

  • 异步方法调用,例如WebClient.UploadStringAsync使用另一个可用线程(线程3)

第三个是我的问题源于的地方,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 回答

  • 3

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

    简短回答:是的 .

    • 根据UploadStringAsync的文档:

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

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

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

    遗憾的是,您无法升级到较新版本的.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.");
        }
    }
    

相关问题