1

「多くの UI コンポーネントがこれを必要とするため、呼び出し元のスレッドは STA でなければなりません」というメッセージとともに InvalidOperationException が発生しています。私のWPFアプリケーション開発で。(エラーが発生している場所を含むコードの下を参照してください)。Canvas gui が構築されており、Canvas コンストラクター自体がこの例外をスローしており、コンストラクターに入っていないため、Participant コンストラクター内でエラーが発生します。

public class Participant : SktParticipant
    {
        public enum PictureMode
        {
            Avatar,
            Video
        }

        public PictureMode pictureMode = PictureMode.Avatar;

        public Canvas gui;
        public VerticalProgressBar voiceVolume;
        public Label nameLabel;
        public VideoRenderer pic;
        public Video video;

        public bool isCachedInClient = false;   // indicates whether displayName and avatarImage have values
        public string displayName = null;
        public Image avatarImage = null;

        public int picHeight = 480;
        public int piclWidth = 640;
        public int panelHeight = 155;
        public int panelWidth = 174;

        public System.Drawing.Color liveColor = System.Drawing.SystemColors.GradientActiveCaption;
        public System.Drawing.Color nonLiveColor = System.Drawing.SystemColors.GradientActiveCaption;

        public Participant(uint objectId, SktSkype skype)
            : base(objectId, skype)
        {
            gui = new Canvas()  //HERE IS THE InvalidOperationException ERROR
            {
                Width = panelWidth,
                Height = panelHeight,
                //BorderStyle = BorderStyle.FixedSingle,
                Background = System.Windows.SystemColors.GradientActiveCaptionBrush
            };
            pic = new VideoRenderer(skypeRef)
            {
                Margin = new System.Windows.Thickness { Left = 5, Top = 5, Right = 0, Bottom = 0 },
                Height = picHeight,
                Width = piclWidth,
                Stretch = Stretch.Fill
            };
            gui.Children.Add(pic);

STA および MTA スレッド化について読んだことがあります (たとえば、「多くの UI コンポーネントがこれを必要とするため、呼び出し元のスレッドは STA でなければなりません。」 WPF )、新しい参加者を作成するスレッドを STA に設定することはできません。エラーが発生したときに、それを呼び出しているスレッド/メソッドを特定できませんでした。次のコードから、 Participant コンストラクターが問題なく呼び出されることを確認しました。

private void callButton_Click(object sender, EventArgs e)
        {
            if (liveSession != null)
            {
                if ((liveSession.P_LOCAL_LIVESTATUS == SktConversation.LOCAL_LIVESTATUS.RINGING_FOR_ME) || 
                    (liveSession.P_LOCAL_LIVESTATUS == SktConversation.LOCAL_LIVESTATUS.OTHERS_ARE_LIVE))
                {
                    liveSession.JoinLiveSession("");
                }
                else
                {
                    if (liveSession == null) return;
                    // if we leave volountarily, while other people are still in a live session,
                    // the liveSession P_LOCAL_LIVESTATUS will remain OTHERS_ARE_LIVE.
                    // So, we need to switch UI mode to not-yet-in-call state here as well.
                    liveSession.LeaveLiveSession(false);
                    liveSession = null;
                    ReleaseWebcam();
                    UiToWaitingMode();
                }
                return;
            }

            if (convListBox.SelectedItem == null) return;

            // Here we actually make the outgoing call
            Conversation conv = (Conversation)convListBox.Items[convListBox.SelectedIndex];
            liveSession = conv;

            // Fetching target list from conv and converting to string list
            SktParticipant.List parts;
            parts = liveSession.GetParticipants(SktConversation.PARTICIPANTFILTER.OTHER_CONSUMERS);             
            foreach (Participant p in parts) { p.RingIt(); }
        }

さまざまなスレッドとオブジェクトのディスパッチャーを使用して、エラーの原因を突き止めようとしました。

このエラーを解決する方法を誰かが知っていますか?

4

1 に答える 1

1

問題は、2番目のケースでは、コードがUIスレッドによって呼び出されることですが、最初のケースでは、それがワーカー/通信スレッドの1つであると思います。DispatcherWPFでは、すべてのUIの変更は、UIスレッドで行うか、特別なオブジェクトを使用してUIスレッドにディスパッチする必要があります。

UIの変更を別のメソッドにラップし、それを使用Application.Current.Dispatcher.Invokeして呼び出します。

この問題とその解決策に関するより詳細な記事は次のとおりです。http://blog.decarufel.net/2009/03/good-practice-to-use-dispatcher-in-wpf.html

于 2012-11-23T11:58:16.170 に答える