关于异步方法调用

luohualiushui 2004-07-20 12:09:10
using System;

namespace ConsoleApplication4
{
public delegate int BinaryOp(int x, int y, ref int z);

public class MathCode {

internal int sum = 0;

public int Add(int m, int n, ref int c) {
System.Threading.Thread.Sleep(5000);
c = m + n;
return c;
}

public int Subtract(int a, int b, ref int c) {
System.Threading.Thread.Sleep(5000);
c = a - b;
return c;
}

public int Multiplication(int a, int b, ref int c) {
System.Threading.Thread.Sleep(5000);
c = a * b;
return c;
}

public int Division(int a, int b, ref int c) {
System.Threading.Thread.Sleep(5000);
c = a / b;
return c;
}
}

class Class1
{

[STAThread]
static void Main(string[] args)
{

MathCode target = new MathCode();

Type tt = typeof(MathCode);
Type dt = typeof(BinaryOp);

BinaryOp op1 = new BinaryOp(target.Division);
int objResult = 0;
IAsyncResult ar = op1.BeginInvoke(100, 10, ref objResult, null, null);

while (!ar.IsCompleted) {
System.Threading.Thread.Sleep(500);
Console.WriteLine("the caculation is still executing!!please wait!!!");
}
Console.WriteLine("this caculation is complete with the result of {0}.", objResult);

}
}
}

最后现实的objResult居然还是0,这是为什么?
...全文
259 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
小贵子88 2004-07-21
  • 打赏
  • 举报
回复
这就是异步编程要注意的地方,以为会返回到ref/out参数中
我是这么认为:ref/out参数也相当于返回值,调用完成以后,需要再去接收
luohualiushui 2004-07-21
  • 打赏
  • 举报
回复
to zmgcj:
我知道"执行这句以后异步调用还没有返回",但是IsComplete变成true的时候函数调用完了吧。
而且我只是传了个ref参数进去,又不是要函数返回值,为什么要“一定要到调用结束以后,才知道返回值是多少”???
lanbaibai 2004-07-20
  • 打赏
  • 举报
回复
你没有用委托代理吧
meixiaofeng 2004-07-20
  • 打赏
  • 举报
回复
up
小贵子88 2004-07-20
  • 打赏
  • 举报
回复
如果在委托的参数中有out或ref参数,因为必须要从目标方法返回,所以在EndInvoke()的参数中,也要包含out和ref参数以让调用者返回。
IAsyncResult ar = op1.BeginInvoke(100, 10, ref objResult, null, null);//理论上,执行这句以后异步调用还没有返回(OS没那么快执行),就直接运行下面的语句了objResult所以还是0,一定要到调用结束以后,才知道返回值是多少,所以要在EndInvoke中取结果,并且EndInvoke会阻塞到直到返回为止。
liulangxin 2004-07-20
  • 打赏
  • 举报
回复
begininvoke仅仅是初始化进程,他返回的是ar,endinvoke才能获得结果
luohualiushui 2004-07-20
  • 打赏
  • 举报
回复
能不能解释一下为什么?
既然已经运行完了(IsCompleted),结果(objResult)就应该变了啊
难道是像数据库一样要COMMIT一次??!
小贵子88 2004-07-20
  • 打赏
  • 举报
回复
在最后Console.Writeline前增加一句取返回值
int i=op1.EndInvoke(ref objResult,ar);
liulangxin 2004-07-20
  • 打赏
  • 举报
回复
using System;

namespace ConsoleApplication4
{
public delegate int BinaryOp(int x, int y, ref int z);

public class MathCode
{

internal int sum = 0;

public int Add(int m, int n, ref int c)
{
System.Threading.Thread.Sleep(5000);
c = m + n;
return c;
}

public int Subtract(int a, int b, ref int c)
{
System.Threading.Thread.Sleep(5000);
c = a - b;
return c;
}

public int Multiplication(int a, int b, ref int c)
{
System.Threading.Thread.Sleep(5000);
c = a * b;
return c;
}

public int Division(int a, int b, ref int c)
{
System.Threading.Thread.Sleep(5000);
c = a / b;
return c;
}
}

class Class1
{

[STAThread]
static void Main(string[] args)
{

MathCode target = new MathCode();

Type tt = typeof(MathCode);
Type dt = typeof(BinaryOp);

BinaryOp op1 = new BinaryOp(target.Division);
int objResult = 0;
IAsyncResult ar = op1.BeginInvoke(100, 10, ref objResult, null, null);

while (!ar.IsCompleted)
{
System.Threading.Thread.Sleep(500);
Console.WriteLine("the caculation is still executing!!please wait!!!");
}
int ret=op1.EndInvoke(ref objResult,ar);
Console.WriteLine("this caculation is complete with the result of {0}.", ret);

}
}
}
luohualiushui 2004-07-20
  • 打赏
  • 举报
回复
是BeginInvoke的最后两个参数的问题吗?
能不能解释一下这两个参数?
程序该怎么改?

谢谢
biihc2000 2004-07-20
  • 打赏
  • 举报
回复
就是啊,BeginInvoke里应该给个委托的吧?!

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧