dotnet/wpf · error · ArgumentException

SR.MediaSystem_ApiInvalidContext

Error message

SR.MediaSystem_ApiInvalidContext

What it means

MediaSystem.AssertSameContext throws ArgumentException when two media-related objects (a reference and 'other') live on different dispatchers. Media objects are bound to the dispatcher/thread they were created on; passing an object from another UI thread's context is rejected.

Solutions

  1. Create and use all related media objects on the same dispatcher/thread
  2. If cross-thread is needed, marshal via Dispatcher.Invoke/BeginInvoke so operations run on the owning thread
  3. Recreate the media object on the target thread instead of reusing it

Example fix

// before
uiThreadMediaPlayer.??? = backgroundCreatedState; // ArgumentException
// after
Dispatcher.FromThread(uiThread).Invoke(() =>
{
    var player = new MediaPlayer(); // create on same thread
    // use player with other UI-thread media objects
});
Defensive patterns

Strategy: validation

Validate before calling

bool SameDispatcher(DispatcherObject a, DispatcherObject b) => a == null || b == null || a.Dispatcher == null || b.Dispatcher == null || a.Dispatcher == b.Dispatcher;

Type guard

bool IsOnSameThread<T>(T mediaObj) where T : DispatcherObject => mediaObj.Dispatcher.CheckAccess();

Try / catch

try { UseMediaObjects(refObj, other); } catch (ArgumentException ex) when (ex.Message.Contains("context")) { RecreateOnCurrentDispatcher(other); }

Prevention

When it happens

Trigger: Passing a MediaPlayer, MediaCapture/context object, or other media resource created on one UI thread into a media API on a different thread where both have non-null but differing Dispatcher properties.

Common situations: Creating MediaPlayer on one window's thread and using it with objects from another window/thread; background-thread media setup then handing the object to the UI thread without recreating it.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/2d68659c16ecaece. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/MediaSystem.cs:282

        /// Note that VerifyContext(A) AND AssertSameContext(A, B) implies that VerifyContext(B) holds. Hence you
        /// don't need to check the context for each argument if you assert the same context.
        /// </remarks>
        internal static void AssertSameContext(
            DispatcherObject reference,
            DispatcherObject other)
        {
            Debug.Assert(reference != null, "The reference object can not be null.");

            // DispatcherObjects may be created with the option of becoming unbound.
            // An unbound DO may be created without a Dispatcher or may detach from
            // its Dispatcher (e.g., a Freezable).  Unbound DOs return null for their
            // Dispatcher and should be accepted anywhere.
            if (other != null &&
                reference.Dispatcher != null &&
                other.Dispatcher != null &&
                reference.Dispatcher != other.Dispatcher)
            {
                throw new ArgumentException(SR.MediaSystem_ApiInvalidContext);
            }
        }

        /// <summary>
        /// This flag indicates if the transport has been disabled by a session disconnect.
        /// If the transport has been disabled we need to defer all media system startup requests
        /// until we get the next connect message
        /// </summary>
        internal static bool IsTransportConnected
        {
            get { return s_isConnected; }
            set { s_isConnected = value; }
        }

        /// <summary>
        /// This flag indicates if all rendering should be in software.
        /// </summary>
        internal static bool ForceSoftwareRendering

View on GitHub (pinned to 81131a70a4)