C# 识别源线程时出现的问题导致;调用线程必须是STA,因为许多UI组件都需要它;在SkypeKit.NET WPF应用程序中

C# 识别源线程时出现的问题导致;调用线程必须是STA,因为许多UI组件都需要它;在SkypeKit.NET WPF应用程序中,c#,.net,wpf,skype,C#,.net,Wpf,Skype,在我的WPF应用程序开发中,我遇到了一个InvalidOperationException,消息是“调用线程必须是STA,因为许多UI组件都需要STA”。(请参见下面的代码以及发生错误的位置)。错误发生在参与者构造函数内部,因为正在构造画布gui,而画布构造函数本身正在引发此异常,而不是进入构造函数 public class Participant : SktParticipant { public enum PictureMode {

在我的WPF应用程序开发中,我遇到了一个InvalidOperationException,消息是“调用线程必须是STA,因为许多UI组件都需要STA”。(请参见下面的代码以及发生错误的位置)。错误发生在参与者构造函数内部,因为正在构造画布gui,而画布构造函数本身正在引发此异常,而不是进入构造函数

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线程的内容(例如),但我无法将创建新参与者的线程设置为STA。。当错误发生时,我无法找到调用它的线程/方法。 我已经看到,从以下代码调用参与者构造函数时没有问题:

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(); }
        }
我尝试使用各种线程和对象的分派器确定错误的来源,确保main()具有STAthread属性,尝试在看似相关的方法上设置“[STAthread]”


有人知道我如何解决这个错误吗?

问题是,在第二种情况下,您的代码由UI线程调用,但在第一种情况下,我认为它是您的工作线程/通信线程之一。在WPF中,所有UI更改必须在UI线程中完成,或者使用特殊的
分派器
对象分派给它

将UI更改包装到一个单独的方法中,并使用
Application.Current.Dispatcher.Invoke
调用它


这里有一篇关于这个问题及其解决方案的更详细的文章:

问题是,在第二种情况下,您的代码由UI线程调用,但在第一种情况下,我假设它是您的工作线程/通信线程之一。在WPF中,所有UI更改必须在UI线程中完成,或者使用特殊的
分派器
对象分派给它

将UI更改包装到一个单独的方法中,并使用
Application.Current.Dispatcher.Invoke
调用它


这里有一篇关于这个问题及其解决方案的更详细的文章:

您从哪里实例化
参与者
构造函数?另一方面,您必须始终在主线程而不是后台线程上创建UI元素。只需查看调用堆栈调试器窗口,了解您是如何做到这一点的。很可能是由于线程池线程上引发的某种事件。您从何处实例化
参与者
构造函数?另一方面,您必须始终在主线程而不是后台线程上创建UI元素。只需查看调用堆栈调试器窗口,了解您是如何做到这一点的。很可能是由于在线程池线程上引发的某种事件。