通过ParameterizedThreadStart按值传递参数(不是参考)

时间:2018-04-05 07:37:04

标签: c# multithreading visual-studio

我试图通过以下方式传递参数(复制而不是参考):

Thread thread = new Thread(new ParameterizedThreadStart(DoMethod));
thread.start(concurrentQueueObj);

但是我发现它是通过引用传递的。同样由BlueM'回答在this question

知道如何通过复制将参数传递给线程吗?我很感激一些帮助。

编辑:我只是希望该线程收到一个参数副本。因此,如果主线程更改concurrentQueueObj,则它对工作线程的参数没有影响。

2 个答案:

答案 0 :(得分:3)

我理解你在问你使用错误的词语时会问你什么。

您未通过引用传递concurrentQueueObj变量,您正在传递concurrentQueueObj变量的 的参考。

简而言之,您传递 引用,而不是 引用。

如果您想了解有关此主题的更多信息,请确保您可以在互联网上找到许多文章,以及Stack Overflow上的质量问题和答案。您可以先阅读Parameter passing in C#上的Jon Skeets文章。

通过引用传递将使用refout个关键字,在更高版本的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将在线程内可用。这真的是并发收集的重点。