110,534
社区成员
发帖
与我相关
我的任务
分享
//按钮事件
private void button3_Click(object sender, EventArgs e)
{
Console.WriteLine($"-------------Thread单击开始,进程数:{Thread.CurrentThread.ManagedThreadId}-------------");
Func<string> oldFunc = new Func<string>(
() =>
{
Thread.Sleep(8000);
return "我是返回值";
}
);
Func<string> newFunc = this.GetThred<string>(oldFunc);
newFunc();
Console.WriteLine($"-------------Thread单击结束,进程数:{Thread.CurrentThread.ManagedThreadId}-------------");
}
//调用方法
public Func<T> GetThred<T>(Func<T> func)
{
T t = default(T);
ThreadStart ts = () =>
{
t = func.Invoke();
Console.WriteLine($"aaaaaaaaaaaa{Thread.CurrentThread.ManagedThreadId}aaaaaaaaaaa");
};
Thread thread = new Thread(ts);
thread.Start();
return () =>
{
Console.WriteLine($"【前】方法里面############{Thread.CurrentThread.ManagedThreadId}###############");
thread.Join();
Console.WriteLine($"【后】方法里面############{Thread.CurrentThread.ManagedThreadId}###############");
return t;
};
}
class X2348923<T>
{
public T value;
public T func()
{
Console.WriteLine($"【前】方法里面############{Thread.CurrentThread.ManagedThreadId}###############");
thread.Join();
Console.WriteLine($"【后】方法里面############{Thread.CurrentThread.ManagedThreadId}###############");
return this.value
}
}
如果有其他打字错误,细节自己理解吧。这里主要是了解这个匿名委托返回了一个编译器自动创建的对象类的实例(的方法委托),而这个对象跟什么线程无关!也跟GetThread 作用于无关。对象在于堆栈中,根本就是跨线程的。
class X2348923<T>
{
public T value;
public T func()
{
Console.WriteLine($"【前】方法里面############{Thread.CurrentThread.ManagedThreadId}###############");
thread.Join();
Console.WriteLine($"【后】方法里面############{Thread.CurrentThread.ManagedThreadId}###############");
return t;
}
}
public Func<T> GetThred<T>(Func<T> func)
{
.............
.............
var xxx= new X2348923<T>();
xxx.vlue = t;
return xxx.func();
}
匿名委托中把变量 t 按照面向对象的机制而封装为临时创建对象实例的属性/字段,然后调用此对象的封装的方法。
此对象的作用域分什么 GetThread 没有关系,对象的函数委托被GetFhread 函数返回,那么 GetThread 函数结束之后,此对象当然还是不能释放的,因为还有引用。至于说什么时候释放,那要看调用者将来的纯粹动态的使用过程而定,什么时候没有引用这个对象了,它就被 GC 自动释放了。
这是那些满脑子只有 c/c++ 静态分配内存概念的人不容易理解的。因为 .net 是真正的面向对象的、自动管理(和释放)对象存储的,不需要开发人员低级地手动静态释放对象存储。