【发布时间】:2021-03-02 16:05:28
【问题描述】:
我在斐波那契方法上运行委托异步回调模式。此静态方法包含一个循环,其中线程休眠 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 模型,但这不是怎么做APM 模型。
-
这个 AMP 模型似乎遵循了我见过的大多数示例。唯一的区别是我正在从方法内的循环中编写后台线程(应该没问题)。当我不使用
BeginInvoke回调功能时,它可以正常工作。EndInvoke似乎工作正常,没有来自 Main() 的回调;但是,它在上述实现中失败了。 -
根本不要使用这种异步编程风格。使用 Tasks 和 TPL 编写异步程序。
-
我没有意识到这种风格已经过时了。上一堂关于这些主题的课,我们似乎首先要上老派。不管怎样,
EndInvoke应该很容易寻址,不是吗?微软几年前发布了异步调用同步方法,使用了这种风格。 -
@ErikSvenBroberg,它不仅仅是过时了。除此之外,还有另外几种风格已经过时,包括 EAP、AsyncEnumerator、RX.Net 等……除非我发现自己在 dotnet 2.0 平台上,否则我不会使用 APM。