@@ -1068,6 +1068,16 @@ public IEnumerable<KeyValuePair<string, string>> EnumerateMetadata()
1068
1068
var list = _itemDefinitions != null ? MetadataCollection : _directMetadata ;
1069
1069
if ( list != null )
1070
1070
{
1071
+ #if FEATURE_APPDOMAIN
1072
+ // Can't send a yield-return iterator across AppDomain boundaries
1073
+ if ( ! AppDomain . CurrentDomain . IsDefaultAppDomain ( ) )
1074
+ {
1075
+ return EnumerateMetadataEager ( list ) ;
1076
+ }
1077
+ #endif
1078
+ // Mainline scenario, returns an iterator to avoid allocating an array
1079
+ // to store the results. With the iterator, results can stream to the
1080
+ // consumer (e.g. binlog writer) without allocations.
1071
1081
return EnumerateMetadata ( list ) ;
1072
1082
}
1073
1083
else
@@ -1076,6 +1086,28 @@ public IEnumerable<KeyValuePair<string, string>> EnumerateMetadata()
1076
1086
}
1077
1087
}
1078
1088
1089
+ /// <summary>
1090
+ /// Used to return metadata from another AppDomain. Can't use yield return because the
1091
+ /// generated state machine is not marked as [Serializable], so we need to allocate.
1092
+ /// </summary>
1093
+ /// <param name="list">The source list to return metadata from.</param>
1094
+ /// <returns>An array of string key-value pairs representing metadata.</returns>
1095
+ private IEnumerable < KeyValuePair < string , string > > EnumerateMetadataEager ( CopyOnWritePropertyDictionary < ProjectMetadataInstance > list )
1096
+ {
1097
+ var result = new List < KeyValuePair < string , string > > ( list . Count ) ;
1098
+
1099
+ foreach ( var projectMetadataInstance in list )
1100
+ {
1101
+ if ( projectMetadataInstance != null )
1102
+ {
1103
+ result . Add ( new KeyValuePair < string , string > ( projectMetadataInstance . Name , projectMetadataInstance . EvaluatedValue ) ) ;
1104
+ }
1105
+ }
1106
+
1107
+ // Probably better to send the raw array across the wire even if it's another allocation.
1108
+ return result . ToArray ( ) ;
1109
+ }
1110
+
1079
1111
private IEnumerable < KeyValuePair < string , string > > EnumerateMetadata ( CopyOnWritePropertyDictionary < ProjectMetadataInstance > list )
1080
1112
{
1081
1113
foreach ( var projectMetadataInstance in list )
@@ -1152,7 +1184,7 @@ internal CopyOnWritePropertyDictionary<ProjectMetadataInstance> MetadataCollecti
1152
1184
1153
1185
IEnumerable < ProjectMetadataInstance > IItem < ProjectMetadataInstance > . Metadata => MetadataCollection ;
1154
1186
1155
- #region Operators
1187
+ #region Operators
1156
1188
1157
1189
/// <summary>
1158
1190
/// This allows an explicit typecast from a "TaskItem" to a "string", returning the ItemSpec for this item.
@@ -1193,7 +1225,7 @@ public static explicit operator string(TaskItem that)
1193
1225
return ! ( left == right ) ;
1194
1226
}
1195
1227
1196
- #endregion
1228
+ #endregion
1197
1229
1198
1230
/// <summary>
1199
1231
/// Produce a string representation.
@@ -1215,7 +1247,7 @@ public override object InitializeLifetimeService()
1215
1247
}
1216
1248
#endif
1217
1249
1218
- #region IItem and ITaskItem2 Members
1250
+ #region IItem and ITaskItem2 Members
1219
1251
1220
1252
/// <summary>
1221
1253
/// Returns the metadata with the specified key.
@@ -1467,9 +1499,9 @@ IDictionary ITaskItem2.CloneCustomMetadataEscaped()
1467
1499
return clonedMetadata ;
1468
1500
}
1469
1501
1470
- #endregion
1502
+ #endregion
1471
1503
1472
- #region INodePacketTranslatable Members
1504
+ #region INodePacketTranslatable Members
1473
1505
1474
1506
/// <summary>
1475
1507
/// Reads or writes the packet to the serializer.
@@ -1499,9 +1531,9 @@ void ITranslatable.Translate(ITranslator translator)
1499
1531
}
1500
1532
}
1501
1533
1502
- #endregion
1534
+ #endregion
1503
1535
1504
- #region IEquatable<TaskItem> Members
1536
+ #region IEquatable<TaskItem> Members
1505
1537
1506
1538
/// <summary>
1507
1539
/// Override of GetHashCode.
@@ -1579,7 +1611,7 @@ public bool Equals(TaskItem other)
1579
1611
return true ;
1580
1612
}
1581
1613
1582
- #endregion
1614
+ #endregion
1583
1615
1584
1616
/// <summary>
1585
1617
/// Returns true if a particular piece of metadata is defined on this item (even if
0 commit comments