.NET 4.0有TPL,它包含了很好的Task类来封装异步编程模型。我正在开发一个必须是.NET 2.0的应用程序,但我想避免重写Task。有什么建议吗?
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 }
4ioopgfo2#
你必须使用System.Threading.Thread类,你可以得到Task类的。net 3.5,但不能为。net 2。对不起
System.Threading.Thread
Task
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
3条答案
按热度按时间pu3pd22g1#
我知道你说过你不想重写Task,但实际上你可以使用闭包创建一些相当简单的东西,它的行为有点像Task对象用途:
它是一个在传入的委托上调用BeginInvoke()的函数,并返回一个在调用时阻塞并等待传入函数结果的函数。当然,您必须为不同的方法签名创建此函数的重载。
一种方法是,你可以根据自己的需要调整它,并添加其他行为,如Continuation等。关键是使用闭包和匿名委托。应该在.NET 2.0中工作。
编辑-以下是您的使用方法:
4ioopgfo2#
你必须使用
System.Threading.Thread
类,你可以得到Task
类的。net 3.5,但不能为。net 2。对不起
whhtz7ly3#
你可以考虑的另一种方法是,你可以把异步任务放在一个单独的进程中,而不是运行一个异步任务线程(正如你发现的那样,.net 2.0并不真正支持这个线程),这个进程将使用.net的更高版本来构建,因此可以使用.net framework的Task异步工作。
这是要包含在.net framework 2. 0应用程序中的代码类型。
然后,您可以将应用程序MyAsynchronousApplication.exe创建为一个单独的项目,并使用所需的任何.net版本。然后,将可执行文件与原始.net 2.0应用程序放在同一目录中。在此示例中,MyAsynchronousApplication.exe接受单个字符串参数,并在第二个线程中反转其字符顺序(有时间限制,只能在1秒或更短时间内完成)。其代码示例如下