读书人

关于delegate的回调方法的使用,该如何

发布时间: 2011-12-29 22:09:38 作者: rapoo

关于delegate的回调方法的使用
rt,谁帮我解答啊.

[解决办法]
该示例说明如何将委托传递给需要函数指针的非托管函数。委托是可以容纳对方法的引用的类,并且等效于类型安全函数指针或回调函数。Microsoft .NET Framework SDK 在 Samples\Technologies\Interop\Platform-Invoke 中包括此示例的完整 Visual Basic .NET 和 C# 版本。
注意 当您在调用内部使用委托时,公共语言运行库将在此调用的持续时间内防止对委托执行垃圾回收。但是,如果非托管函数存储该委托以供在该调用完成后使用,则您必须手动防止进行垃圾回收,直到非托管函数完成对该委托的使用为止。有关更多信息,请参见 HandleRef 示例和 GCHandle 示例。
Callback 示例使用以下非托管函数(这里同时显示其原始函数声明):
从 PinvokeLib.dll 导出的 TestCallBack。
void TestCallBack(FPTR pf, int value);
从 PinvokeLib.dll 导出的 TestCallBack2。
void TestCallBack2(FPTR2 pf2, char* value);
PinvokeLib.dll 是一个自定义非托管库,它包含前面列出的函数的实现。
在该示例中,LibWrap 类包含 TestCallBack 和 TestCallBack2 方法的托管原型。这两个方法都将委托作为参数传递给回调函数。该委托的签名必须与它所引用的方法的签名相匹配。例如,FPtr 和 FPtr2 委托的签名与 DoSomething 和 DoSomething2 方法的签名相同。
声明原型
[Visual Basic]
Public Delegate Function FPtr( ByVal value As Integer ) As Boolean
Public Delegate Function FPtr2( ByVal value As String ) As Boolean

Public Class LibWrap
' Declares managed prototypes for unmanaged functions.
Declare Sub TestCallBack Lib "..\LIB\PinvokeLib.dll " ( ByVal cb _
As FPtr, ByVal value As Integer )
Declare Sub TestCallBack2 Lib "..\LIB\PinvokeLib.dll " ( ByVal cb2 _
As FPtr2, ByVal value As String )
End Class 'LibWrap
[C#]
public delegate bool FPtr( int value );
public delegate bool FPtr2( String value );

public class LibWrap
{// Declares managed prototypes for unmanaged functions.
[ DllImport( "..\\LIB\\PinvokeLib.dll " )]
public static extern void TestCallBack( FPtr cb, int value );
[ DllImport( "..\\LIB\\PinvokeLib.dll " )]
public static extern void TestCallBack2( FPtr2 cb2, String value );
}
调用函数
[Visual Basic]
Public Class App
Public Shared Sub Main()

Dim cb As FPtr
cb = AddressOf App.DoSomething
Dim cb2 As FPtr2
cb2 = AddressOf App.DoSomething2
LibWrap.TestCallBack( cb, 99 )
LibWrap.TestCallBack2( cb2, "abc " )
End Sub 'Main
Public Shared Function DoSomething( ByVal value As Integer ) As Boolean
Console.WriteLine( ControlChars.CrLf + "Callback called with _
param: {0} ", value )
...
End Function 'DoSomething
Public Shared Function DoSomething2( ByVal value As String ) As Boolean
Console.WriteLine( ControlChars.CrLf + "Callback called with _
param: {0} ", value )
...
End Function 'DoSomething2
End Class 'App
[C#]
public class App
{
public static void Main()
{
FPtr cb = new FPtr( App.DoSomething );
LibWrap.TestCallBack( cb, 99 );
FPtr2 cb2 = new FPtr2( App.DoSomething2 );
LibWrap.TestCallBack2( cb2, "abc " );
}

public static bool DoSomething( int value )
{
Console.WriteLine( "\nCallback called with param: {0} ", value );
...
}
public static bool DoSomething2( String value )
{
Console.WriteLine( "\nCallback called with param: {0} ", value );
...
}
}

[解决办法]
自己看例子吧
using System;
using System.Threading;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;

// Create an asynchronous delegate.
public delegate bool FactorizingAsyncDelegate (
int factorizableNum,
ref int primefactor1,


ref int primefactor2);

// Create a class that factorizers the number.
public class PrimeFactorizer
{
public bool Factorize(
int factorizableNum,
ref int primefactor1,
ref int primefactor2)
{
primefactor1 = 1;
primefactor2 = factorizableNum;

// Factorize using a low-tech approach.
for (int i=2;i <factorizableNum;i++)
{
if (0 == (factorizableNum % i))
{
primefactor1 = i;
primefactor2 = factorizableNum / i;
break;
}
}

if (1 == primefactor1 )
return false;
else
return true ;
}
}

// Class that receives a callback when the results are available.
public class ProcessFactorizedNumber
{
private int _ulNumber;

public ProcessFactorizedNumber(int number)
{
_ulNumber = number;
}

// Note that the qualifier is one-way.
[OneWayAttribute()]
public void FactorizedResults(IAsyncResult ar)
{
int factor1=0, factor2=0;

// Extract the delegate from the AsyncResult.
FactorizingAsyncDelegate fd = (FactorizingAsyncDelegate)((AsyncResult)ar).AsyncDelegate;

// Obtain the result.
fd.EndInvoke(ref factor1, ref factor2, ar);

// Output the results.
Console.WriteLine( "On CallBack: Factors of {0} : {1} {2} ",
_ulNumber, factor1, factor2);
}
}

// Class that shows variations of using Asynchronous
public class Simple
{
// The following demonstrates the Asynchronous Pattern using a callback.
public void FactorizeNumber1()
{
// The following is the client code.
PrimeFactorizer pf = new PrimeFactorizer();
FactorizingAsyncDelegate fd = new FactorizingAsyncDelegate (pf.Factorize);

int factorizableNum = 1000589023, temp=0;

// Create an instance of the class that is going
// to be called when the call completes.
ProcessFactorizedNumber fc = new ProcessFactorizedNumber(factorizableNum);

// Define the AsyncCallback delegate.
AsyncCallback cb = new AsyncCallback(fc.FactorizedResults);

// You can use any object as the state object.
Object state = new Object();

// Asynchronously invoke the Factorize method on pf.
IAsyncResult ar = fd.BeginInvoke(
factorizableNum,
ref temp,
ref temp,
cb,
state);

//
// Do some other useful work.
//. . .
}

// The following demonstrates the Asynchronous Pattern using a BeginInvoke, followed by waiting with a time-out.
public void FactorizeNumber2()
{
// The following is the client code.
PrimeFactorizer pf = new PrimeFactorizer();
FactorizingAsyncDelegate fd = new FactorizingAsyncDelegate (pf.Factorize);

int factorizableNum = 1000589023, temp=0;

// Create an instance of the class that is going
// to be called when the call completes.
ProcessFactorizedNumber fc = new ProcessFactorizedNumber(factorizableNum);

// Define the AsyncCallback delegate.
AsyncCallback cb =
new AsyncCallback(fc.FactorizedResults);

// You can use any object as the state object.


Object state = new Object();

// Asynchronously invoke the Factorize method on pf.
IAsyncResult ar = fd.BeginInvoke(
factorizableNum,
ref temp,
ref temp,
null,
null);

ar.AsyncWaitHandle.WaitOne(10000, false);

if (ar.IsCompleted)
{
int factor1=0, factor2=0;

// Obtain the result.
fd.EndInvoke(ref factor1, ref factor2, ar);

// Output the results.

Console.WriteLine( "Sequential : Factors of {0} : {1} {2} ",
factorizableNum, factor1, factor2);

}
}


public static void Main(String[] args)
{
Simple simple = new Simple();
simple.FactorizeNumber1();
simple.FactorizeNumber2();
}
}

读书人网 >C#

热点推荐