C# 使用异步委托获取线程返回值

发布时间:2023年12月17日

写在前面

异步委托主要用于解决?ThreadPool.QueueUserWorkItem?没有提供获取线程执行完成后的返回值问题。异步委托只能在.Net Framework 框架下使用,.Net Core中会报平台错误,而且使用Task.Result来获取返回值,可以达成同样的目的;本文纯粹是做个验证试验。

代码实现

        static void Main(string[] args)
        {
            AsyncResultTest();
            Console.WriteLine("OK");
            Console.ReadKey();
        }

        public static void AsyncResultTest()
        {
            var str = "hello";
            var testOb = new TestOb() { msg = str };
            Func<TestOb, int> testMethod = Dosomething;
            //testMethod.BeginInvoke(testOb, Done, testMethod);
            var asyncResult = testMethod.BeginInvoke(testOb, null, null);
            var task01 = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(1000);
                testOb.msg = "hello world";
                Console.WriteLine($"task01 exceuted str is {testOb.msg}");
            });
            task01.Wait();
            var result = testMethod.EndInvoke(asyncResult);
            Console.WriteLine($"AsyncResultTest finished, result is {result}");
        }

        private static int Dosomething(TestOb testOb)
        {
            Console.WriteLine($"Dosomething:{testOb.msg}");
            Thread.Sleep(2000);
            return testOb.msg.Length;
        }

        private static void Done(IAsyncResult result)
        {
            var asyncState = (Func<TestOb, int>)result.AsyncState;
            var retVal = asyncState.EndInvoke(result);
            Console.WriteLine($"result is:{retVal}");
        }

        class TestOb
        {
            public string msg { get; set; }
        }

执行结果

.Net Core 下实现类似效果的代码:

        public static void TaskReturnValueTest()
        {
            var value = "000";
            var task01 = Task.Factory.StartNew(() =>
            {
                value = "111";
                Thread.Sleep(1000);
                Console.WriteLine($"task01 exceuted value is {value}.");
                return "1";
            });
            var task02 = Task.Factory.StartNew(() =>
            {
                Thread.Sleep(800);
                value = "222";
                Console.WriteLine($"task02 exceuted value is {value}.");
                return "2";
            });
            Task.WaitAll(task01, task02);
            var ret01 = task01.Result;
            var ret02 = task02.Result;
            Console.WriteLine($"task01: {ret01}, task02: {ret02}");
            Console.WriteLine("Ok");
        }

执行结果:?

总结?

用Task类库的代码实现方式明显更优,更易于理解和维护。

文章来源:https://blog.csdn.net/rjcql/article/details/134960394
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。