• 0

c# Win Store App: Thread error


Question

Hello gang,

 

I'm having an interesting error and looking at the what/how others are dealing with it is not helping.

 

I am using some code from MS so I can display visualizations within my app (code found here:  http://www.getcodesamples.com/src/5D67423E )

 

 

The interesting thing is I am getting the following error: The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

 

Here is the code to start the player, this works fine:

private MMAudioPlayer.Player BediaAudioPlayer

async private void PlayAudio(MenuItem BediaMenu)
            {
                try
                {
                    if (BediaAudioPlayer == null)
                    {
                        BediaAudioPlayer = new MMAudioPlayer.Player();
                    }

                    if (BediaMenu.MenuFile != null)
                    {
                        string sPath = BediaMenu.MenuFile.Path;
                        StorageFile AudioFile = await StorageFile.GetFileFromPathAsync(sPath);
                        IRandomAccessStream AudioStream = await AudioFile.OpenAsync(Windows.Storage.FileAccessMode.Read);
                        BediaAudioPlayer.SetAudioData(AudioStream);
                        BediaAudioPlayer.Vol = Convert.ToSingle(this.MediaVolume);
                    }
                }
                catch (Exception ex)
                {
                    LogException(ex);
                }
            }

However, when the audio completes in this code I get that error

 private void BediaAudioPlayer_OnEndOfStream(MMAudioPlayer.EndOfStreamReason paramaters)
            {
                try
                {
                    if (paramaters == MMAudioPlayer.EndOfStreamReason.ok)
                    {
                        mMainPage.BediaTitleBar.MenuTitle = "This is a test";    //error is here.
                    }
                }
                catch (Exception ex)
                {
                    LogException(ex);
                }
            }

mMainPage is the application's MainPage and all the code listed above is from my class BediaEngine.  I can call functions btw the two with no issues, with the exception of this one.  What am I doing wrong?

public MainPage()
        {
            this.InitializeComponent();
                        
            objBediaEngine = new BediaEngine(this); //The plan is that almost all of the work is done within this engine, only minor interfaces to the UI
}
Link to comment
Share on other sites

5 answers to this question

Recommended Posts

  • 0

Wrap your code with where you indicated the error is with that and it should work. :)

The EndOfStream event is being called by the main thread but the event handler code is actually called by a separate one (I think.)

Async methods run on their own thread so the event is essentially fire-and-forget so you have to use the dispatcher to send your event code to the original thread.

Link to comment
Share on other sites

  • 0

Try using this.Dispatcher.Invoke()

You're trying to change a control that's owned by another thread.

Let me make a test case to make sure I give you the right info and I'll update this.

 

            this.Dispatcher.Invoke(delegate()
            {
                // control access goes here
            });
Link to comment
Share on other sites

  • 0

Try using this.Dispatcher.Invoke()

You're trying to change a control that's owned by another thread.

 

 

Eric,

 

You're always around, so thanks for that.

 

I got that the msg is saying that this is on another thread...  what I don't understand is how this is on another thread and how do I specifically resolve this?    I see you're statement on Dispatch, but I really don't understand which code to affect.

 

Yea, I'm sure I look stupid right now...  I know. (at least I will admit it)

 

EDIT: What I am trying to say is I'm trying to have more of an understanding than simply; "fix this for me"

Link to comment
Share on other sites

  • 0

GUI objects can only be modified from the thread that they were created in. So when you attempted to change it on a different thread an exception was thrown.
By sending it to the dispatcher, it makes sure that the GUI object is modified on the GUI thread.

Link to comment
Share on other sites

  • 0

Eric,

 

Thanks, that was VERY helpful.  Not completely right for a Windows Store app, but so close that I got there.

 

If you're ever in NYC, drink on me.

private CoreDispatcher BediaDispatcher;


public BediaEngine(MainPage mainPage)
{
    BediaDispatcher = Window.Current.Dispatcher;
}



  private async void BediaAudioPlayer_OnEndOfStream(MMAudioPlayer.EndOfStreamReason paramaters)
            {
                try
                {
                    if (paramaters == MMAudioPlayer.EndOfStreamReason.ok)
                    {
                        await BediaDispatcher.RunAsync(CoreDispatcherPriority.Normal, () => 
                            {
                                AudioTimer.Stop();
                                MediaSelect(1);
                            });
                    }
                }
                catch (Exception ex)
                {
                    LogException(ex);
                }
            }
Link to comment
Share on other sites

This topic is now closed to further replies.