我试图通过以下方式传递参数(复制而不是参考):
Thread thread = new Thread(new ParameterizedThreadStart(DoMethod));
thread.start(concurrentQueueObj);
但是我发现它是通过引用传递的。同样由BlueM'回答在this question
知道如何通过复制将参数传递给线程吗?我很感激一些帮助。
编辑:我只是希望该线程收到一个参数副本。因此,如果主线程更改concurrentQueueObj,则它对工作线程的参数没有影响。
答案 0 :(得分:3)
我理解你在问你使用错误的词语时会问你什么。
您未通过引用传递concurrentQueueObj
变量,您正在传递concurrentQueueObj
变量的值 是的参考。
简而言之,您传递 引用,而不是 引用。
如果您想了解有关此主题的更多信息,请确保您可以在互联网上找到许多文章,以及Stack Overflow上的质量问题和答案。您可以先阅读Parameter passing in C#上的Jon Skeets文章。
通过引用传递将使用ref
或out
个关键字,在更高版本的C#中使用in
关键字。
然而,我理解的问题是:
我可以将
concurrentQueueObj
对象的副本传递给线程,这样如果它或我(启动线程的代码)之后修改了这个对象,那就不会泄漏进入不同的线程?
从一般意义上说,答案既是肯定的,也是肯定的。
一般内置于C#编程语言或.NET运行时和库平台中通常解决此问题。
然而,你可以做的是自己制作一个副本,然后传入。完全如何做到这完全取决于传入的对象的类型。例如,如果它是{{1}你可以简单地在它上面调用List<T>
,然后你会得到一个新列表。
然而,不,会获得列表中 内所有对象的副本。这些仍将在原始列表和副本之间共享。
唯一的#34;复制方法&#34; 100%万无一失的是创建对象的深层副本,这意味着您可以克隆/复制其中包含的每个对象。
有许多数据结构,都内置于.NET中并可作为NuGet包提供,旨在以不同方式解决部分问题,例如不可变数据结构和集合等。哪些适用于您的场景取决于该变量的类型。
如果您想阅读有关传递 引用与 引用的更多信息,在.NET和C#中有两个轴可以解决此问题:
和
您将这两个轴的所有组合组合在一起,因此如果您想了解更多相关信息,请务必了解它的含义:
按值传递值类型
这是一份副本
通过引用传递值类型
是指向保存值的变量的引用指针 型
按值传递参考类型
是引用的副本,但不是引用的对象
通过引用传递引用类型
是对包含引用类型的变量的引用
答案 1 :(得分:3)
编辑:我只是希望该线程收到一个参数副本。因此,如果主线程更改concurrentQueueObj,则它对工作线程的参数没有影响。
如果主线程
thread.start(concurrentQueueObj);
concurrentQueueObj = null;
然后你的线程代码不会注意到一件事。
但是,它确实像
那样thread.start(concurrentQueueObj);
concurrentQueueObj.Enqueue(someData);
然后当然someData
将在线程内可用。这真的是并发收集的重点。