Skip to content

Commit bccaecb

Browse files
authored
Update clarify $using and using thread-safe types (#11284)
1 parent 6ef8be0 commit bccaecb

File tree

4 files changed

+194
-116
lines changed

4 files changed

+194
-116
lines changed

reference/5.1/Microsoft.PowerShell.Core/About/about_Scopes.md

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: Explains the concept of scope in PowerShell and shows how to set and change the scope of elements.
33
Locale: en-US
4-
ms.date: 06/07/2024
4+
ms.date: 07/22/2024
55
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-5.1&WT.mc_id=ps-gethelp
66
schema: 2.0.0
77
title: about Scopes
@@ -60,7 +60,7 @@ hierarchy of child scopes whose root scope is the global scope.
6060
> Modules have their own session state that's linked to the scope in which the
6161
> module was imported. All module code runs in a module-specific hierarchy of
6262
> scopes that has its own root scope. For more information, see the
63-
> [Modules][02] section of this article.
63+
> [Modules][03] section of this article.
6464
6565
When a child scope is created, it includes all the aliases and variables that
6666
have the **AllScope** option, and some automatic variables. This option is
@@ -90,7 +90,7 @@ When a reference is made to a variable, alias, or function, PowerShell searches
9090
the current scope. If the item isn't found, the parent scope is searched. This
9191
search is repeated all they way up to the global scope. If a variable is
9292
private in a parent scope, the search through continues through the scope
93-
chain. [Example 4][01] shows the effect of a private variable in a scope
93+
chain. [Example 4][02] shows the effect of a private variable in a scope
9494
search.
9595

9696
## PowerShell scopes names
@@ -128,14 +128,14 @@ optional scope modifiers:
128128
current scope.
129129

130130
> [!NOTE]
131-
> `private:` isn't a scope. It's an [option][03] that changes the
131+
> `private:` isn't a scope. It's an [option][04] that changes the
132132
> accessibility of an item outside of the scope in which it's defined.
133133
134134
- `script:` - Specifies that the name exists in the **Script** scope.
135135
**Script** scope is the nearest ancestor script file's scope or **Global** if
136136
there is no nearest ancestor script file.
137137
- `using:` - Used to access variables defined in another scope while running
138-
scripts via cmdlets like `Start-Job` and `Invoke-Command`.
138+
in remote sessions, background jobs, or thread jobs.
139139
- `workflow:` - Specifies that the name exists within a workflow. Note:
140140
Workflows aren't supported in PowerShell v6 and higher.
141141
- `<variable-namespace>` - A modifier created by a PowerShell **PSDrive**
@@ -266,16 +266,34 @@ Depending on the context, embedded variable values are either independent
266266
copies of the data in the caller's scope or references to it. In remote and
267267
out-of-process sessions, they're always independent copies.
268268

269-
For more information, see [about_Remote_Variables][07].
269+
For more information, see [about_Remote_Variables][08].
270270

271-
In thread sessions, they're passed by reference. This means it's possible to
272-
modify child scope variables in a different thread. To safely modify variables
273-
requires thread synchronization.
271+
A `$using:` reference only expands to a variable's value. If you want to change
272+
the value of a variable in the caller's scope, you must have a reference to the
273+
variable itself. You can create a reference to a variable by getting the
274+
**PSVariable** instance of the variable. The following example show how to
275+
create a reference and make changes in a thread job.
274276

275-
For more information see:
277+
```powershell
278+
$Count = 1
279+
$refOfCount = Get-Variable Count
280+
281+
Start-ThreadJob {
282+
($using:refOfCount).Value = 2
283+
} | Receive-Job -Wait -AutoRemoveJob
284+
285+
$Count
286+
```
276287

277-
- [Start-ThreadJob][11]
278-
- [ForEach-Object][10]
288+
```Output
289+
2
290+
```
291+
292+
> [!NOTE]
293+
> This is not a thread-safe operation. You can cause data corruption if you try
294+
> to change the value from multiple threads at the same time. You should use
295+
> thread-safe data types or synchronization primitives to protect shared data.
296+
> For more information, see [Thread-Safe collections][01].
279297
280298
### Serialization of variable values
281299

@@ -387,7 +405,7 @@ Using the call operator is no different than running the script by name.
387405
& c:\scripts\sample.ps1
388406
```
389407

390-
You can read more about the call operator in [about_Operators][06].
408+
You can read more about the call operator in [about_Operators][07].
391409

392410
To run the `Sample.ps1` script in the local scope type a dot and a space (`. `)
393411
before the path to the script:
@@ -736,21 +754,21 @@ The `using` scope modifier was introduced in PowerShell 3.0.
736754

737755
## See also
738756

739-
- [about_Variables][09]
740-
- [about_Environment_Variables][04]
741-
- [about_Functions][05]
742-
- [about_Script_Blocks][08]
743-
- [Start-ThreadJob][11]
757+
- [about_Environment_Variables][05]
758+
- [about_Functions][06]
759+
- [about_Script_Blocks][09]
760+
- [about_Variables][10]
761+
- [Start-ThreadJob][12]
744762

745763
<!-- link references -->
746-
[01]: #example-4-creating-a-private-variable
747-
[02]: #modules
748-
[03]: #private-option
749-
[04]: about_Environment_Variables.md
750-
[05]: about_Functions.md
751-
[06]: about_Operators.md
752-
[07]: about_Remote_Variables.md
753-
[08]: about_Script_Blocks.md
754-
[09]: about_Variables.md
755-
[10]: xref:Microsoft.PowerShell.Core.ForEach-Object
756-
[11]: xref:ThreadJob.Start-ThreadJob
764+
[01]: /dotnet/standard/collections/thread-safe/
765+
[02]: #example-4-creating-a-private-variable
766+
[03]: #modules
767+
[04]: #private-option
768+
[05]: about_Environment_Variables.md
769+
[06]: about_Functions.md
770+
[07]: about_Operators.md
771+
[08]: about_Remote_Variables.md
772+
[09]: about_Script_Blocks.md
773+
[10]: about_Variables.md
774+
[12]: xref:ThreadJob.Start-ThreadJob

reference/7.2/Microsoft.PowerShell.Core/About/about_Scopes.md

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
description: Explains the concept of scope in PowerShell and shows how to set and change the scope of elements.
33
Locale: en-US
4-
ms.date: 06/07/2024
4+
ms.date: 07/22/2024
55
online version: https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_scopes?view=powershell-7.2&WT.mc_id=ps-gethelp
66
schema: 2.0.0
77
title: about Scopes
@@ -60,7 +60,7 @@ hierarchy of child scopes whose root scope is the global scope.
6060
> Modules have their own session state that's linked to the scope in which the
6161
> module was imported. All module code runs in a module-specific hierarchy of
6262
> scopes that has its own root scope. For more information, see the
63-
> [Modules][02] section of this article.
63+
> [Modules][03] section of this article.
6464
6565
When a child scope is created, it includes all the aliases and variables that
6666
have the **AllScope** option, and some automatic variables. This option is
@@ -90,7 +90,7 @@ When a reference is made to a variable, alias, or function, PowerShell searches
9090
the current scope. If the item isn't found, the parent scope is searched. This
9191
search is repeated all they way up to the global scope. If a variable is
9292
private in a parent scope, the search through continues through the scope
93-
chain. [Example 4][01] shows the effect of a private variable in a scope
93+
chain. [Example 4][02] shows the effect of a private variable in a scope
9494
search.
9595

9696
## PowerShell scopes names
@@ -128,14 +128,14 @@ optional scope modifiers:
128128
current scope.
129129

130130
> [!NOTE]
131-
> `private:` isn't a scope. It's an [option][03] that changes the
131+
> `private:` isn't a scope. It's an [option][04] that changes the
132132
> accessibility of an item outside of the scope in which it's defined.
133133
134134
- `script:` - Specifies that the name exists in the **Script** scope.
135135
**Script** scope is the nearest ancestor script file's scope or **Global** if
136136
there is no nearest ancestor script file.
137137
- `using:` - Used to access variables defined in another scope while running
138-
scripts via cmdlets like `Start-Job` and `Invoke-Command`.
138+
in remote sessions, background jobs, or thread jobs.
139139
- `workflow:` - Specifies that the name exists within a workflow. Note:
140140
Workflows aren't supported in PowerShell v6 and higher.
141141
- `<variable-namespace>` - A modifier created by a PowerShell **PSDrive**
@@ -266,16 +266,34 @@ Depending on the context, embedded variable values are either independent
266266
copies of the data in the caller's scope or references to it. In remote and
267267
out-of-process sessions, they're always independent copies.
268268

269-
For more information, see [about_Remote_Variables][07].
269+
For more information, see [about_Remote_Variables][08].
270270

271-
In thread sessions, they're passed by reference. This means it's possible to
272-
modify child scope variables in a different thread. To safely modify variables
273-
requires thread synchronization.
271+
A `$using:` reference only expands to a variable's value. If you want to change
272+
the value of a variable in the caller's scope, you must have a reference to the
273+
variable itself. You can create a reference to a variable by getting the
274+
**PSVariable** instance of the variable. The following example show how to
275+
create a reference and make changes in a thread job.
274276

275-
For more information see:
277+
```powershell
278+
$Count = 1
279+
$refOfCount = Get-Variable Count
280+
281+
Start-ThreadJob {
282+
($using:refOfCount).Value = 2
283+
} | Receive-Job -Wait -AutoRemoveJob
284+
285+
$Count
286+
```
276287

277-
- [Start-ThreadJob][11]
278-
- [ForEach-Object][10]
288+
```Output
289+
2
290+
```
291+
292+
> [!NOTE]
293+
> This is not a thread-safe operation. You can cause data corruption if you try
294+
> to change the value from multiple threads at the same time. You should use
295+
> thread-safe data types or synchronization primitives to protect shared data.
296+
> For more information, see [Thread-Safe collections][01].
279297
280298
### Serialization of variable values
281299

@@ -387,7 +405,7 @@ Using the call operator is no different than running the script by name.
387405
& c:\scripts\sample.ps1
388406
```
389407

390-
You can read more about the call operator in [about_Operators][06].
408+
You can read more about the call operator in [about_Operators][07].
391409

392410
To run the `Sample.ps1` script in the local scope type a dot and a space (`. `)
393411
before the path to the script:
@@ -736,21 +754,23 @@ The `using` scope modifier was introduced in PowerShell 3.0.
736754

737755
## See also
738756

739-
- [about_Variables][09]
740-
- [about_Environment_Variables][04]
741-
- [about_Functions][05]
742-
- [about_Script_Blocks][08]
743-
- [Start-ThreadJob][11]
757+
- [about_Environment_Variables][05]
758+
- [about_Functions][06]
759+
- [about_Script_Blocks][09]
760+
- [about_Variables][10]
761+
- [ForEach-Object][11]
762+
- [Start-ThreadJob][12]
744763

745764
<!-- link references -->
746-
[01]: #example-4-creating-a-private-variable
747-
[02]: #modules
748-
[03]: #private-option
749-
[04]: about_Environment_Variables.md
750-
[05]: about_Functions.md
751-
[06]: about_Operators.md
752-
[07]: about_Remote_Variables.md
753-
[08]: about_Script_Blocks.md
754-
[09]: about_Variables.md
755-
[10]: xref:Microsoft.PowerShell.Core.ForEach-Object
756-
[11]: xref:ThreadJob.Start-ThreadJob
765+
[01]: /dotnet/standard/collections/thread-safe/
766+
[02]: #example-4-creating-a-private-variable
767+
[03]: #modules
768+
[04]: #private-option
769+
[05]: about_Environment_Variables.md
770+
[06]: about_Functions.md
771+
[07]: about_Operators.md
772+
[08]: about_Remote_Variables.md
773+
[09]: about_Script_Blocks.md
774+
[10]: about_Variables.md
775+
[11]: xref:Microsoft.PowerShell.Core.ForEach-Object
776+
[12]: xref:ThreadJob.Start-ThreadJob

0 commit comments

Comments
 (0)