Skip to content

Commit db022c0

Browse files
committed
Take Items snapshot if any item is a __TransparentProxy
Even if we are in the default AppDomain it can happen that TaskParameterEventArgs is created in the default AppDomain, but the Items passed to it originate from a different AppDomain. We have to detect this case and take the items snapshot immediately otherwise that AppDomain can get unloaded.
1 parent b67e3d9 commit db022c0

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/ItemGroupLoggingHelper.cs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections;
66
using System.Collections.Generic;
77
using System.Globalization;
8+
using System.Runtime.Remoting;
89
using Microsoft.Build.BackEnd.Logging;
910
using Microsoft.Build.Collections;
1011
using Microsoft.Build.Framework;
@@ -288,11 +289,39 @@ internal static TaskParameterEventArgs CreateTaskParameterEventArgs(
288289

289290
private static void CreateItemsSnapshot(ref IList items)
290291
{
291-
if (items == null || AppDomain.CurrentDomain.IsDefaultAppDomain())
292+
if (items == null)
292293
{
293294
return;
294295
}
295296

297+
#if FEATURE_APPDOMAIN
298+
// If we're in the default AppDomain, but any of the items come from a different AppDomain
299+
// we need to take a snapshot of the items right now otherwise that AppDomain might get
300+
// unloaded by the time we want to consume the items.
301+
// If we're not in the default AppDomain, always take the items snapshot.
302+
//
303+
// It is unfortunate to need to be doing this check, but ResolveComReference and other tasks
304+
// still use AppDomains and create a TaskParameterEventArgs in the default AppDomain, but
305+
// pass it Items from another AppDomain.
306+
if (AppDomain.CurrentDomain.IsDefaultAppDomain())
307+
{
308+
bool needsSnapshot = false;
309+
foreach (var item in items)
310+
{
311+
if (RemotingServices.IsTransparentProxy(item))
312+
{
313+
needsSnapshot = true;
314+
break;
315+
}
316+
}
317+
318+
if (!needsSnapshot)
319+
{
320+
return;
321+
}
322+
}
323+
#endif
324+
296325
int count = items.Count;
297326
var cloned = new object[count];
298327

0 commit comments

Comments
 (0)