System.UnauthorizedAccessException - 无效的跨线程访问

时间:2014-07-03 14:48:19

标签: c# visual-studio windows-phone-8

我的应用程序非常简单,使用数据绑定时遇到问题。我已经成功下载了这个例子:http://msdn.microsoft.com/en-us/magazine/hh852595.aspx

有" next"按钮,生成新人并将其加载到应用程序中。

但是我尝试做同样的事情,我得到以下例外:System.UnauthorizedAccessException - Invalid cross-thread access

我试着对此做同样的事情:

    public Chat()
    {
        InitializeComponent();
        bindingChat.leftText = "jooooo2";
        ContentPanel.DataContext = bindingChat;
    }   

    private void connect(object sender, XmppConnectedEventArgs target)
    {
        bindingChat = new BindingChat();
        bindingChat.leftText = "Connected";
        ContentPanel.DataContext = bindingChat; //this is where the exception is thrown
    }

文字" jooooo2"按预期工作,但是当调用connet方法时,会出现提到的异常。

在正在运行的示例中,他们使用以下代码设置了新人(点击按钮后):

    private void SetDataContext()
    {
        GeneratePerson();
        ContentPanel.DataContext = _currentPerson;
    }

它运作正常。


编辑:

好的,我发现这是因为间接调用它:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        xmpp1.OnConnected += new Xmpp.OnConnectedHandler(connect);
        xmpp1.IMServer = "***";
        xmpp1.IMPort = 5222;
        xmpp1.Connect("user1", "heslouser1");
        xmpp1.ChangePresence(1, "I'm here!");
    }

如果我尝试使用其他按钮直接更改它,它会按预期工作:

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        bindingChat = new BindingChat();
        bindingChat.leftText = "button pressed";
        ContentPanel.DataContext = bindingChat;
    }

1 个答案:

答案 0 :(得分:0)

好吧,我在http://www.codeproject.com/Articles/368983/Invoking-through-the-Dispatcher-on-Windows-Phone-a

找到了解决方案

这是一个有效的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using nsoftware.IPWorks;
using myNamespace.ViewModel;

namespace myNamespace
{
    public partial class Chat : PhoneApplicationPage
    {
        private Xmpp xmpp1 = new Xmpp();
        private Xmpp xmpp2 = new Xmpp();
        private BindingChat bindingChat = new BindingChat();

        public Chat()
        {
            InitializeComponent();
            bindingChat.leftText = "jooooo2";
            xmpp1.OnConnected += new Xmpp.OnConnectedHandler(connect);
            ContentPanel.DataContext = bindingChat;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            xmpp1.IMServer = "***";
            xmpp1.IMPort = 5222;
            xmpp1.Connect("user1", "heslouser1");
            xmpp1.ChangePresence(1, "I'm here!");
        }

        private void connect(object sender, XmppConnectedEventArgs target)
        {
            DispatchInvoke(() =>
            {
                bindingChat = new BindingChat();
                bindingChat.leftText = "Connected";
                ContentPanel.DataContext = bindingChat;
            }
        );
        }    

        public void DispatchInvoke(Action a)
        {

#if SILVERLIGHT
            if (Dispatcher == null)
                a();
            else
                Dispatcher.BeginInvoke(a);
#else
    if ((Dispatcher != null) && (!Dispatcher.HasThreadAccess))
    {
        Dispatcher.InvokeAsync(
                    Windows.UI.Core.CoreDispatcherPriority.Normal, 
                    (obj, invokedArgs) => { a(); }, 
                    this, 
                    null
         );
    }
    else
        a();
#endif
        }

    }
}