要在.NET 2.0中使用Task,我应该做些什么< T>?

r1zk6ea1  于 2023-03-20  发布在  .NET
关注(0)|答案(3)|浏览(116)

.NET 4.0有TPL,它包含了很好的Task类来封装异步编程模型。我正在开发一个必须是.NET 2.0的应用程序,但我想避免重写Task。有什么建议吗?

pu3pd22g

pu3pd22g1#

我知道你说过你不想重写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()的函数,并返回一个在调用时阻塞并等待传入函数结果的函数。当然,您必须为不同的方法签名创建此函数的重载。
一种方法是,你可以根据自己的需要调整它,并添加其他行为,如Continuation等。关键是使用闭包和匿名委托。应该在.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

    }
4ioopgfo

4ioopgfo2#

你必须使用System.Threading.Thread类,你可以得到Task类的。net 3.5,但不能为。net 2。
对不起

whhtz7ly

whhtz7ly3#

你可以考虑的另一种方法是,你可以把异步任务放在一个单独的进程中,而不是运行一个异步任务线程(正如你发现的那样,.net 2.0并不真正支持这个线程),这个进程将使用.net的更高版本来构建,因此可以使用.net framework的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

相关问题