Vb.net多线程条件下,给委托方法传参数
来源:互联网 发布:文怀沙 知乎 编辑:程序博客网 时间:2024/04/28 13:17
呵呵,放了这么久鸽子,主要是因为自己对委托的了解还不是特别的深刻,另外需要读一些C#代码,对C#的一些细节了解的也不够。借口应该够充分了。
那好,正经事,先说委托。
委托是一种数据结构,它引用静态(shared in Vb/static inC#)方法或引用类实例及该类的实例方法。委托其实就是类似C++的函数指针,只是它安全性更好...如此云云。更多的资料参考参考资料【1】和【2】【6】这三部分的内容。个人感觉委托这地方有点乱,主要是因为设计函数过程操作,另外Vb和C#在实现细节上也有很多的不同。另外,在声明上总有点别扭。了解c++的,直接把它当指针最好,那样好理解点。
委托说完了,再来看看线程
Thead,线程。一个进程里可以构建很多的线程,从而更好的提高进程性能和响应能力,更细致的看baidu百科,那的资料更全面。:)
threadpool,线程池,可用于发送工作项、处理异步 I/O、代表其他线程等待以及处理计时器。参考【3】
名词解释完了,写段样例代码,正常的带参数的委托代码,只是用于表述带参数委托的使用。可能设计上有不妥的地方,没有仔细推敲。
Module Module1
Public Class Dog
Sub New()
Me._hungry = True
End Sub
Sub New(ByVal Name As String)
Me._name = Name
Me._hungry = True
End Sub
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _hungry As Boolean
Public Property Hungry() As Boolean
Get
Return _hungry
End Get
Set(ByVal value As Boolean)
_hungry = value
End Set
End Property
'重写Object的Tostring方法
Public Overrides Function Tostring() As String
Return Me.Name
End Function
End Class
''' <summary>
''' 静态方法封装类
''' </summary>
''' <remarks></remarks>
Public Class SharedFunc
Public Shared Sub Feed(ByVal Obj As Dog)
If Obj.Hungry Then
Console.Write("Feed" & Obj.Tostring())
Obj.Hungry = False
End If
End Sub
End Class
Delegate Sub MyDelegate(ByVal Obj As Dog)
Sub Main()
Dim MyFeed As New MyDelegate(AddressOf SharedFunc.Feed)
Dim DaH As Dog = New Dog("DaHuang")
MyFeed(DaH)
End Sub
End Module
还是纯阐述概念,现在我们打算Feed很多只小狗,于是我们把多线程技术加到上面的代码里,主要修改main()过程
<MTAThread()> _
Sub Main()
'Dim MyFeed As New MyDelegate(AddressOf SharedFunc.Feed)
Dim DaH As Dog = New Dog("DaHuang")
DaH.Hungry = True
'MyFeed(DaH)
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SharedFunc.Feed(DaH)))
End Sub
等等,这样的代码IDE提示,"Addressof"操作数必须是某个方法的名称。其实在上面的代码里,Waitcallback本身是个委托类型,Addressof应该接函数的地址,当然没有办法传参数了。
而WaitcallBack是框架定义的委托类型。
看看WaitcallBack的委托定义。
<ComVisibleAttribute(True)> _
Public Delegate Sub WaitCallback ( _
state As Object _
)
state as object ? 这个是做什么的?
包含回调方法要使用的信息的对象。正是它。再看看QueueUserWorkItem重载了两个函数。呵呵Object?和我们传的类型不符?这个不困难,只要转换就好。
为了保持委托函数与委托的一致性,需要适当修改下委托函数的参数代码,毕竟State是Object对象。新的多线程代码
Imports system.Threading
Module Module1
Public Class Dog
Sub New()
Me._hungry = True
End Sub
Sub New(ByVal Name As String)
Me._name = Name
Me._hungry = True
End Sub
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Private _hungry As Boolean
Public Property Hungry() As Boolean
Get
Return _hungry
End Get
Set(ByVal value As Boolean)
_hungry = value
End Set
End Property
'重写Object的Tostring方法
Public Overrides Function Tostring() As String
Return Me.Name
End Function
End Class
''' <summary>
''' 静态方法封装类
''' </summary>
''' <remarks></remarks>
Public Class SharedFunc
Public Shared Sub Feed(ByVal Obj As Object)
If Obj Is Nothing Then
Console.Write("Obj is nothing")
Else
Obj = Convert.ChangeType(Obj, GetType(Dog))
End If
If Obj.Hungry Then
Console.Write("Feed" & Obj.ToString())
Obj.Hungry = False
End If
End Sub
End Class
'Delegate Sub WaitCallback(ByVal Obj As Dog)
<MTAThread()> _
Sub Main()
'Dim MyFeed As New MyDelegate(AddressOf SharedFunc.Feed)
Dim DaH As Dog = New Dog("DaHuang")
'MyFeed(DaH)
DaH = DirectCast(DaH, Object)
Dim xiaoB As Dog = New Dog("XiaoBai")
xiaoB = DirectCast(xiaoB, Object)
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SharedFunc.Feed), DaH)
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf SharedFunc.Feed), xiaoB)
'Thread.Sleep(1000)
End Sub
End Module
这样就实现了代码的多线程化。
后续的一些讨论,如果传的参数不是一个,而是多个,该如何处理?
这个问题比较简单,从这也能看出微软工程师在设计上的巧妙之处,因为在.net中所有的对象都是继承自Object对象。这么做,使State对象有了最大的适应性。(写跑了好像?)当需要传多个参数时,只需要把这些参数封装成一个类对象就可以了。然后把封装后的对象传进去。
下面发个C#的实现,C#在重写Tostring()后,和字符串拼接和VB.net有些区别,不是重点,所以省去那个重写方法
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace DelegateCSharp
{
public class Dog
{
public Dog()
{
this._hungry = true;
}
public Dog(string Name)
{
this._name = Name;
this._hungry = true;
}
private string _name;
public string Name {
get { return _name; }
set { _name = value; }
}
private bool _hungry;
public bool Hungry {
get { return _hungry; }
set { _hungry = value; }
}
}
/// <summary>
/// 静态方法封装类
/// </summary>
/// <remarks></remarks>
public class SharedFunc
{
public static void Feed(Dog Obj)
{
if (Obj.Hungry) {
Console.Write("Feed" + Obj.Name);
Obj.Hungry = false;
}
}
}
class Program
{
[MTAThread()]
static void Main(string[] args)
{
Dog DaH = new Dog("DaHuang");
//MyFeed(DaH)
//DaH = (object)DaH;
Dog xiaoB = new Dog("XiaoBai");
//xiaoB = (object)xiaoB;
ThreadPool.QueueUserWorkItem(delegate { SharedFunc.Feed(DaH); });
ThreadPool.QueueUserWorkItem(delegate { SharedFunc.Feed(xiaoB); });
Thread.Sleep(1000);
}
}
}
这段C#代码和前面的Vb.net代码实现是一样的。但你是否发现C#的代码要比VB.Net代码简洁很多,并没有使用类型转换的部分,取而代之的是一句.
ThreadPool.QueueUserWorkItem(delegate { SharedFunc.Feed(DaH); });
玄机就在这delegate后边的{},正是这个{}实现了函数过程的直接带参数调用
那VB.net就没有办法了?很可惜的说,对于2002、2003、2005,起码我还没有找到更合适的办法。不过值得庆幸的是。VB.Net 2008开始支持lambda表达式。看CSDN论坛里有人用lambda表达式来写。具体怎么写,找不到了。关于Lambda表达式的资料参考【5】.通过Lambda表达式也可以实现类似匿名函数这样的写法,不过可能只能实现一行函数代码的书写,不适合多行。因为现在还在用2005,关于lambda的部分有待日后探讨。
参考资料:
【1】Delegate类
http://msdn.microsoft.com/zh-cn/library/system.delegate(VS.80).aspx
【2】委托(C#)
http://msdn.microsoft.com/zh-cn/library/900fyy8e(VS.80).aspx
【3】Threadpool类
http://msdn.microsoft.com/zh-cn/system.threading.threadpool.aspx
【4】C# 匿名方法
http://msdn.microsoft.com/zh-cn/library/0yw3tz5k(VS.80).aspx
【5】Lambda 表达式
http://msdn.microsoft.com/zh-cn/magazine/cc163362.aspx
【6】何时使用委托而不使用接口(C# 编程指南)
http://msdn.microsoft.com/zh-cn/library/ms173173(VS.80).aspx
- Vb.net多线程条件下,给委托方法传参数
- VB.Net的多线程及委托
- VB.Net的多线程及委托
- VB.NET中的委托
- 匿名方法---将代码块作为参数传递给委托
- [VB.NET]多线程——参数和返回值.txt
- [VB.NET]多线程——线程参数和返回值
- vb.net委托简单研究
- [VB.NET]委托调用---invoke
- VB.NET委托的使用
- vb.net 线程委托写法
- vb.net的委托调用
- 关于VB.NET的委托
- VB.NET委托的使用
- VB.NET委托一例
- VB.net使用多线程与委托解决时间延迟的问题
- vb.net利用webbrowser下载(加载完成判断、多线程、委托)
- vb.net多线程例子
- 隐藏INPUT
- struts2 Action中获取request, response对象的方法
- Repeater问题。知道的麻烦帮忙解决下
- C# Interface Based Development
- 基于windows mobile 5.0 开发环境配置说明
- Vb.net多线程条件下,给委托方法传参数
- 实在想不出,,啊……
- 成功人士必看的5个故事
- Java中的Annotation解析(一)
- VB.Net链接Access的方法
- Studio e.go!全游戏 CG100%+回想存档包
- Java中的Annotation解析(二)
- arm linux 下中断流程简要分析--注册中断
- orcale时间比较