我应该如何使用Task<;T>;在.NET 2.0中
本文关键字:NET gt Task lt 我应该 何使用 | 更新日期: 2023-09-27 18:00:49
.NET4.0具有TPL,其中包含用于封装异步编程模型的漂亮Task类。我正在开发一个必须是.NET 2.0的应用程序,但我想避免重写Task。有什么建议吗?
我知道你说过你不想重写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