如何解决异步委托 EndInvoke 终止循环早于预期
我在斐波那契方法上运行委托异步回调模式。此静态方法包含一个循环,其中线程休眠 300 毫秒以打印出后台线程池 ID。不幸的是,在我的 FibCompleted() 中,EndInvoke 方法正在终止我的进程。任何提示都会有所帮助。 谢谢。
public delegate int FibPointer(int x); // FibbonaciSequence() pointer
class Program
{
static void Main(string[] args)
{
// fibonacci Length
int fibLength = 8;
// point delegate to method
FibPointer fb = new FibPointer(FibonacciSequence);
IAsyncResult iftAR = fb.BeginInvoke(
fibLen,new AsyncCallback(FibCompleted),null);
Console.WriteLine("Fibonacci process Now running on thread {0}\n",Thread.CurrentThread.ManagedThreadId);
int count = 0;
while (!iftAR.IsCompleted) // completion occurs when userIN length is reached
{
// run fib sequence.
Console.WriteLine("{0}",FibonacciSequence(count));
count++;
}
Console.ReadKey();
}
static int FibonacciSequence(int num)
{
int num1 = 0,num2 = 1,res = 0;
if (num == 0) return 0;
if (num == 1) return 1;
for (int i = 0; i < num; i++)
{
res = num1 + num2;
num1 = num2;
num2 = res;
Thread.Sleep(300);
// track background thread from pool
Console.WriteLine("Working on thread: {0}",Thread.CurrentThread.ManagedThreadId);
}
return res;
}
static void FibCompleted(IAsyncResult ar)
{
Console.WriteLine("\nFib Sequence Completed.");
// retrieve result
AsyncResult res = (AsyncResult)ar;
//FibPointer fp = ar.AsyncState as FibPointer;
FibPointer fp = res.AsyncDelegate as FibPointer;
// call EndInvoke to grab results
string returnVal = fp.EndInvoke(ar).ToString();
Console.WriteLine("\nreturn val is: {0}",returnVal);
}
}
解决方法
如果您必须使用纯 APM。下面是它的一个例子。
void Main()
{
// fibonacci Length
int fibLength = 8;
// point delegate to method
Func<int,int> fb = FibonacciSequence;
var completedEvent = new System.Threading.AutoResetEvent(false);
var iftAR = fb.BeginInvoke(fibLength,FibCompleted,completedEvent);
completedEvent.WaitOne();
var result = fb.EndInvoke(iftAR);
Console.WriteLine("Fibonacci process now running on thread {0}\n",Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(result);
}
static int FibonacciSequence(int num)
{
int num1 = 0,num2 = 1,res = 0;
if (num == 0) return 0;
if (num == 1) return 1;
for (int i = 0; i < num; i++)
{
res = num1 + num2;
num1 = num2;
num2 = res;
Thread.Sleep(300);
// track background thread from pool
Console.WriteLine("Working on thread: {0}",Thread.CurrentThread.ManagedThreadId);
}
return res;
}
static void FibCompleted(IAsyncResult ar)
{
var completedEvent = (AutoResetEvent)ar.AsyncState;
completedEvent.Set();
}
不过。没有人再使用纯 APM。 APM 被 EAP 取代,EAP 又被 TAP 取代。
我建议您改为学习 TAP。它要简单得多。要将 APM 代码调整为 TAP,您可以使用 TaskFactory 辅助函数。
async Task Main()
{
// fibonacci Length
int fibLength = 8;
// point delegate to method
Func<int,int> fb = FibonacciSequence;
var result = await Task.Factory.FromAsync (fb.BeginInvoke,fb.EndInvoke,fibLength,null);
Console.WriteLine("Fibonacci process now running on thread {0}\n",Thread.CurrentThread.ManagedThreadId);
}
return res;
}
但是,大多数人只会在 TAP 中工作。看起来像这样。
async Task Main()
{
// fibonacci Length
int fibLength = 8;
var result = await FibonacciSequence(fibLength);
Console.WriteLine("Fibonacci process now running on thread {0}\n",Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(result);
}
static Task<int> FibonacciSequence(int num)
{
// Run computationally intensive work on thread pool.
return Task.Run(() =>
{
int num1 = 0,res = 0;
if (num == 0) return 0;
if (num == 1) return 1;
for (int i = 0; i < num; i++)
{
res = num1 + num2;
num1 = num2;
num2 = res;
Thread.Sleep(300);
// track background thread from pool
Console.WriteLine("Working on thread: {0}",Thread.CurrentThread.ManagedThreadId);
}
return res;
});
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。