我应该如何使用Task<;T>;在.NET 2.0中

本文关键字:NET gt Task lt 我应该 何使用 | 更新日期: 2023-09-27 18:00:49

.NET4.0具有TPL,其中包含用于封装异步编程模型的漂亮Task类。我正在开发一个必须是.NET 2.0的应用程序,但我想避免重写Task。有什么建议吗?

我应该如何使用Task<;T>;在.NET 2.0中

我知道你说过你不想重写Task,但实际上你可以使用闭包创建一些相当简单的东西,它的行为有点像Task对象。这就是我使用的:

    public delegate R AsyncTask<R>();
    public static AsyncTask<R> BeginTask<R>(AsyncTask<R> function)
    {
        R retv = default(R);
        bool completed = false;
        object sync = new object();
        IAsyncResult asyncResult = function.BeginInvoke(
                iAsyncResult =>
                {
                    lock (sync)
                    {
                        completed = true;
                        retv = function.EndInvoke(iAsyncResult);
                        Monitor.Pulse(sync); 
                    }
                }, null);
        return delegate
        {
            lock (sync)
            {
                if (!completed)               
                {
                    Monitor.Wait(sync); 
                }
                return retv;
            }
        };
    }

它是一个对传入的委托调用BeginInvoke((的函数,并返回一个函数,该函数在被调用时会阻塞并等待传入函数的结果。当然,您必须为不同的方法签名创建该函数的重载。

一种方法是,您可以根据需要调整它,并添加其他行为,如Continuations等。关键是使用闭包和匿名委托。应该在.NET 2.0中工作。

编辑-以下是如何使用它:

    public static string HelloWorld()
    {
        return "Hello World!"; 
    }
    static void Main(string[] args)
    {
        var task = BeginTask(HelloWorld); // non-blocking call
        string result = task(); // block and wait
    }

您必须使用System.Threading.Thread类,您可以为.net 3.5获得Task类,但不能为.net 2获得。

抱歉

您可以考虑的另一种方法是,您可以将异步任务放在一个单独的进程中,而不是让异步任务线程运行(正如您发现的那样,.net 2.0并不真正支持异步任务线程(。这个过程将使用.net的更高版本构建,因此可以使用.net框架的Task异步工作。

这是要包含在.net framework 2.0应用程序中的代码类型。

using System;
using System.Diagnostics;
namespace MyNameSpace
{
    public class MyClass
    {
        private Boolean DoMyTaskAsynchronously( )
        { 
            Boolean                         Boolean_Result = false;
            String                          String_ApplicationDirectory = AppDomain.CurrentDomain.BaseDirectory.Trim( );
            if( !( String.IsNullOrEmpty( String_Directory)))
            { 
                String_Directory = String_Directory.Replace( "/", ( String)( ( System.IO.Path.DirectorySeparatorChar).ToString( )));
                if( !( String_Directory.EndsWith( ( String)( ( System.IO.Path.DirectorySeparatorChar).ToString( )))))
                {
                    String_Directory += System.IO.Path.DirectorySeparatorChar;
                }
                String                      String_ExecutableFileName = "MyAsynchronousApplication.exe";
                String                      String_Argument = "MyArgument";
                Process                     process = new Process( );
                process.StartInfo.FileName = String_ApplicationDirectory + String_ExecutableFileName;
                process.StartInfo.Arguments = "'"" + String_Argument + "'"";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.Start( );
                String                      String_Output = process.StandardOutput.ReadToEnd( ).ToUpper( );
                process.WaitForExit( );
                Boolean_Result = ! String.IsNullOrEmpty( String_Output);
            }//if( !( String.IsNullOrEmpty( String_Directory)))
            return Boolean_Result;
        }//private Boolean DoMyTaskAsynchronously( )
    }//public class MyClass
}//namespace MyNameSpace

然后,您可以将应用程序MyAsynchronousApplication.exe创建为一个单独的项目,并使用您想要的任何.net版本。然后将可执行文件放在与原始.net 2.0应用程序相同的目录中。在本例中,MyAsynchronousApplication.exe采用单个字符串参数,并在第二个线程中反转其字符顺序(时间限制为1秒或更短(。其代码的一个例子是

using System;
using System.Threading.Tasks;
namespace MyAsynchronousApplicationNameSpace
{
    class MyAsynchronousApplicationClass
    {
        static void Main( String[] f_a_String_Arguments)
        {
            String                                      String_ThisProgramName = System.AppDomain.CurrentDomain.FriendlyName.ToLower( );
            String                                      String_CallingProgramName = Environment.CommandLine.ToLower( );
            Boolean                                     Boolean_CalledFromCommandLine = String_CallingProgramName.IndexOf( String_ThisProgramName) == 0;
            if( !( Boolean_CalledFromCommandLine))
            {
                String                                  String_Argument = f_a_String_Arguments[ 0];
                if( !( String.IsNullOrWhiteSpace( String_Argument)))
                { 
                    String                              String_ReversedArgument = FlipTheOrderOfTheArgumentCharactersAsynchronously( String_Argument);
                    if( !( String.IsNullOrWhiteSpace( String_ReversedArgument)))
                    { 
                        Console.WriteLine( String_ReversedArgument); 
                    }
                    else
                    {
                        Console.WriteLine( "MyAsynchronousApplication.exe failure"); 
                    }
                }
                else
                {
                    Console.WriteLine( "No argument supplied to MyAsynchronousApplication.exe"); 
                }
            }
            else
            {
                Console.WriteLine( "The executable file MyAsynchronousApplication.exe can not be invoked from the command line.");
            }
        }//static void Main( String[] f_a_String_Arguments)
        private static String FlipTheOrderOfTheArgumentCharactersAsynchronously( String f_r_String)
        { 
            String                              String_Result = "";
            Task<String>                        task = new Task<String>( ( ) => { return ReverseCharacterOrder( f_r_String);});
            Int32                               Int32_WaitTime = 1000;
            task.Start( );
            if( task.Wait( Int32_WaitTime))
            {
                String_Result = task.Result;
            }
            return String_Result;
        }//private Boolean FlipTheOrderOfTheArgumentCharactersAsynchronously( ref String f_r_String)
        public static String ReverseCharacterOrder( String f_String)
        {
            char[] a_char = f_String.ToCharArray();
            Array.Reverse( a_char);
            return new String( a_char);
        }//public static String ReverseCharacterOrder( String f_String)
    }//class MyAsynchronousApplicationClass
}//namespace MyAsynchronousApplicationNameSpace