c#用委托实现异步主动回调主程序的问题

wangji666666 2009-12-18 11:43:24
程序中要实现这样的功能,在主程序中显示程序集(有好几个程序集a1,a2,a3)运行的状态(每个程序集中都有个定时,不断刷新状态),这些程序集都继承另外一个程序集——a,我想让主程序调用每个程序集的时候,让这些程序集都调用主程序的一个方法,这个方法就是显示各个程序集运行的状态。具体应该怎么做呢?
我现在就是在a中声明一个委托Del,在a中一个类aClass有个属性,就是Del,然后让所有继承a的程序集都有这样一个属性,这样我想在主程序中自己指定方法,让程序集运行时都调用这个方法。但是我不知道怎么调用。下面贴下我写的有问题的DEMO。(请指教如何实现上述功能)
//程序集a
namespace myInterFace
{
public delegate string Del(string param);
public class TestIF
{
public Del d = null;
}
}
//程序集a1
namespace CTestOne
{
public class TClassOne : TestIF
{
public TClassOne()
{
System.Timers.Timer t = new System.Timers.Timer(2000);
t.Interval = 2000;
t.AutoReset = true;
t.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
t.Enabled = true;
}
public void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
{
d("CTestOne"+System.DateTime.Now.ToString());
}
}
}
//主程序
{
myInterFace.Del = aaa;//出现编译错误(aaa为一个函数用来显示程序集的执行时间)//Error 1 'myInterFace.Del' is a 'type', which is not valid in the given context E:\C#Code\动态调用程序集回调\delegateInvokeApp\delegateInvoke\Form1.cs 22 25 delegateInvoke

testIf.d("abc");
string callingDomainName = AppDomain.CurrentDomain.FriendlyName;
AppDomain ad = AppDomain.CreateDomain("test load dll");
InvokeDll obj = (InvokeDll)ad.CreateInstanceFromAndUnwrap(@"delegateInvoke.exe", "delegateInvoke.InvokeDll");
string s = @"E:\C#Code\动态调用程序集回调\delegateInvokeApp\CTestOne\bin\Debug\CTestOne.dll";
obj.LoadAssembly(s);

if (obj.Invoke(testIf,"123"))
textBox1.Text="InvokeOk";
else
textBox1.Text="InvokeFalse";
AppDomain.Unload(ad);
obj = null;
}
...全文
244 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangji666666 2009-12-18
  • 打赏
  • 举报
回复
to soarandy
你说的很对!跟我要说的那个功能一样,我就是想达到这样的功能,让主程序响应程序集的事件,然后通过事件中参数传递,得到程序集的结果,不知道这样子是如果实现的。
wangji666666 2009-12-18
  • 打赏
  • 举报
回复
等于实现了C++中的回调函数啊,让动态库自动回调主函数,类似于这样的功能,C#应该怎么实现啊?
soarandy 2009-12-18
  • 打赏
  • 举报
回复
"我想让主程序调用每个程序集的时候,让这些程序集都调用主程序的一个方法,这个方法就是显示各个程序集运行的状态。"

要想这样,就出现了穿叉调用,在程序集中调用主程序,似乎没有必要,因为有把主程序传到程序集中。可以尝试在 //程序集a1 中添加事件,这样在主程序中调用时就可以接收 //程序集a1 中的事件。
足球中国 2009-12-18
  • 打赏
  • 举报
回复
是基类里加个东西。记录下状态。

再把各个的状态写在基类的。静态属性当中。
应该就是这样吧。




___________________________________
我写的vs2005源代码管理器,只有团队资源管理中源码管理的功能。
http://topic.csdn.net/u/20091203/10/ca40b678-5443-4a18-a9f6-fad9051d0797.html
wangji666666 2009-12-18
  • 打赏
  • 举报
回复
分不够可以再加啊
wangji666666 2009-12-18
  • 打赏
  • 举报
回复
走过路过的能否提供个思路啊?
龙宜坡 2009-12-18
  • 打赏
  • 举报
回复
接口换成基类可能更好点,比如System.Windows.Form类


关于事件发布请参考:如何:发布符合 .NET Framework 准则的事件(C# 编程指南)
龙宜坡 2009-12-18
  • 打赏
  • 举报
回复
接口

using System;

namespace SomethingsBase
{
/// <summary>
/// 接口
/// </summary>
public interface ISomething
{
event EventHandler<ReportStatuEventArgs> ReportStatuEvent;
void DoSoething();
void OnDoSomething(ReportStatuEventArgs rsea);
}

/// <summary>
/// 自定义的事件参数
/// </summary>
public class ReportStatuEventArgs : EventArgs
{
public ReportStatuEventArgs(string s)
{
msg = s;
}
private string msg;
public string Message
{
get { return msg; }
}
private DateTime startTime = DateTime.Now;
public DateTime StartTime
{
get { return startTime; }
}

}
}


实现

using System;
using System.Collections.Generic;
using System.Text;
using SomethingsBase;

namespace DoSomethings
{
public class DoSomething:ISomething
{
#region ISomething 成员

public event EventHandler<ReportStatuEventArgs> ReportStatuEvent;

public void DoSoething()
{
//...
//某种情况下引发事件
ReportStatuEventArgs e = new ReportStatuEventArgs("做某件事");

OnDoSomething(e);
//...
}

public void OnDoSomething(ReportStatuEventArgs rsea)
{
EventHandler<ReportStatuEventArgs> handler = ReportStatuEvent;
if (handler != null)
{
handler(this, rsea);
}
}

#endregion
}
}


主程序

using System;
using SomethingsBase;

namespace EventTest
{
class Program
{
static void Main(string[] args)
{
//这里可以用反射加载对象,示例为了简单就直接new出来了
ISomething some = new DoSomethings.DoSomething();
//指定事件方法
some.ReportStatuEvent+=new EventHandler<ReportStatuEventArgs>(some_ReportStatuEvent);

for (int i = 0; i < 20; i++)
{
some.DoSoething();
System.Threading.Thread.Sleep(500);
}

Console.ReadKey();
}

static void some_ReportStatuEvent(object sender, ReportStatuEventArgs e)
{
Console.WriteLine(e.Message +" 在 " + e.StartTime.ToString("HH:mm:ss"));
}
}
}


执行结果:

做某件事 在 16:29:42
做某件事 在 16:29:43
做某件事 在 16:29:44
做某件事 在 16:29:44
做某件事 在 16:29:45
做某件事 在 16:29:45
做某件事 在 16:29:46
做某件事 在 16:29:46
做某件事 在 16:29:47
做某件事 在 16:29:47
做某件事 在 16:29:48
做某件事 在 16:29:48
做某件事 在 16:29:49
做某件事 在 16:29:49
做某件事 在 16:29:50
做某件事 在 16:29:50
做某件事 在 16:29:51
做某件事 在 16:29:51
做某件事 在 16:29:52
做某件事 在 16:29:52
龙宜坡 2009-12-18
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 wangji666666 的回复:]
to goga21cn
你说的就是我想实现的,具体该怎么做,能写个简单的例子吗?只要关键代码就可以了,就像我上面的a,a1,里面写个简单的实现就好
[/Quote]


稍等。。。
wangji666666 2009-12-18
  • 打赏
  • 举报
回复
其实这个帖子就是为了解决如何让程序集调用主程序方法的问题,有谁能够帮忙啊
wangji666666 2009-12-18
  • 打赏
  • 举报
回复
//程序集a1
namespace CTestOne
{
public class TClassOne : TestIF
{
public TClassOne()
{
System.Timers.Timer t = new System.Timers.Timer(2000);
t.Interval = 2000;
t.AutoReset = true;
t.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
t.Enabled = true;
}
public void OnTimedEvent(object source, System.Timers.ElapsedEventArgs e)
{
d("CTestOne"+System.DateTime.Now.ToString());
}
}
}
里面d("CTestOne"+System.DateTime.Now.ToString()); 这句话是不是有问题?
wangji666666 2009-12-18
  • 打赏
  • 举报
回复
to goga21cn
你说的就是我想实现的,具体该怎么做,能写个简单的例子吗?只要关键代码就可以了,就像我上面的a,a1,里面写个简单的实现就好
龙宜坡 2009-12-18
  • 打赏
  • 举报
回复
基类中定义一个事件,实现里某处地方引发此事件,主程序里将此事件实例化到具体方法。

wangji666666 2009-12-18
  • 打赏
  • 举报
回复
我是C#初学者,关于怎么用代码实现还不会,你们能提供些例子代码吗
wangji666666 2009-12-18
  • 打赏
  • 举报
回复
有例子代码吗?
much0726 2009-12-18
  • 打赏
  • 举报
回复
程序集中使用事件,
主程序挂接这个事件到一个方法中去,这个方法来响应由程序集中通知的事件。

我的思路。
HarveyYan 2009-12-18
  • 打赏
  • 举报
回复
未详细研究过,说一下我的看法参考一下:
(1)myInterFace.Del = aaa; 报错原因是myInterFace.Del 只是定义一下委托的类型,还不是变量所以不能赋值的。可写成 myInterFace.Del myDelegate ; myDelegate=aaa;
(2)感觉定义一个全局变量应该可以实现你的功能。

111,123

社区成员

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

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

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