简体   繁体   中英

Invalid cross-thread access Windows Azure

I am developing an Windows Phone 8 app using Windows Azure Mobile Services.

I have the following code:

private async void appBarButton1_Click(object sender, EventArgs e)
    {
        var table = App.MobileService.GetTable<ChatRoomOverview.chatrooms>();
        //TODO 
        List<ChatRoomOverview.chatrooms> ChatRooms = await table.Where(chat => chat.chatroomName == ChatroomName.Text).ToListAsync();
        if (ChatRooms.Count() < 1)
        {
            ChatRoomOverview.chatrooms ChatRoom = new ChatRoomOverview.chatrooms { chatroomName = ChatroomName.Text, Created = DateTime.Today.Date.ToString(), content = ChatRoomOverview.userName + "|:::|" + FirstPost.Text + "|::|::|", LastPost = FirstPost.Text + "|::|::|", tag1 = tag1.Text, tag2 = tag2.Text, tag3 = tag3.Text, isPrivate = isPrivateCheck.IsChecked.Value, userName = ChatRoomOverview.userName, Popular = "0" };

            await table.InsertAsync(ChatRoom);
            long tempID =ChatRoom.Id;
            await subscripeToNewChatRoom(tempID);

            NavigationService.Navigate(new Uri("/ChatRoomOverview.xaml", UriKind.Relative));
        }
        else
        {
            MessageBox.Show("This Chatroom is allready created go to Search and check it out :)", "Chatroom Exists!", MessageBoxButton.OK);
        }
    }

The above code is excuted when a user wants to create a chatroom. Everything works here. But in my new iteration of the app I want to implement pushnotification, and therefore I want to use a subsription table. This is introduced in the subscripeToNewChatRoom function. Its variable is the issued ID for the chatroom given upon inserting the chatroom item. This value is existing and is correct.

    private System.Threading.Tasks.Task subscripeToNewChatRoom(long tempID)
    {
        ChatRoomOverview.Subscription Subscription = new ChatRoomOverview.Subscription { ContentID = Convert.ToInt32(tempID), userId = App.UserInfromationID };
        **ERROR** App.MobileService.GetTable<ChatRoomOverview.Subscription>().InsertAsync(Subscription);
        return null;
    }

The above code is then excuted to insert the subscription. This code works other places in the code, so I do not understand what the error is. But the error occurs where I have written error in the code. The full exception is in the bottom of the question.

So I do not get why I get why I get the Invalid cross-thread access?

Extra Okay so on the basis of Jaihind answer and comments, I came up with the code below. And I can now see that the tables that I interact with get the correct data. Buuut I still get the exception.

private async void bwSubscription_DoWork(object sender, DoWorkEventArgs e)
    {
        List<object> genericlist = e.Argument as List<object>;

        var table = await App.MobileService.GetTable<ChatRoomOverview.chatrooms>();
        //List<ChatRoomOverview.chatrooms> ChatRooms = table.Where(chat => chat.chatroomName == ChatroomName.Text)

        //table.InsertAsync(ChatRoom);
        ChatRoomOverview.chatrooms chat = (ChatRoomOverview.chatrooms)genericlist[0];
        //var ChatRoom = table.Where(chatting => chatting.chatroomName == chat.chatroomName).ToListAsync();

        long tempID = chat.Id;

        ChatRoomOverview.Subscription Subscription = new ChatRoomOverview.Subscription { ContentID = tempID, userId = App.UserInfromationID };
        await App.MobileService.GetTable<ChatRoomOverview.Subscription>().InsertAsync(Subscription);
    }

But when inserting try/catch, to handle the exception which does not happen, the item will not be inserted in the azure table.

Working Solution

    private async void bwSubscription_DoWork(object sender, DoWorkEventArgs e)
    {
        bool subscriped = false;
        List<object> genericlist = e.Argument as List<object>;

        var table = App.MobileService.GetTable<ChatRoomOverview.chatrooms>();
        //List<ChatRoomOverview.chatrooms> ChatRooms = table.Where(chat => chat.chatroomName == ChatroomName.Text)

        //table.InsertAsync(ChatRoom);
        ChatRoomOverview.chatrooms chat = (ChatRoomOverview.chatrooms)genericlist[0];
        //var ChatRoom = table.Where(chatting => chatting.chatroomName == chat.chatroomName).ToListAsync();

        long tempID = chat.Id;
        while (!subscriped)
        {
            try
            {
                ChatRoomOverview.Subscription Subscription = new ChatRoomOverview.Subscription { ContentID = tempID, userId = App.UserInfromationID , Notifications = 0};
                await App.MobileService.GetTable<ChatRoomOverview.Subscription>().InsertAsync(Subscription);
            }
            catch
            {

            }
            List<ChatRoomOverview.Subscription> subscript = await App.MobileService.GetTable<ChatRoomOverview.Subscription>().Where(subs => subs.ContentID == tempID && subs.userId == App.UserInfromationID && subs.Notifications == 0).ToListAsync();
            if (subscript.Count > 0)
            {
                ChatRoomOverview.userName = "";
                subscriped = true;
            }
            else
            {
                subscriped = false;
            }
        }

    }

My Exception in full

  • $exception {System.UnauthorizedAccessException: Invalid cross-thread access. at MS.Internal.XcpImports.CheckThread() at MS.Internal.XcpImports.MessageBox_ShowCore(String messageBoxText, String caption, UInt32 type) at System.Windows.MessageBox.ShowCore(String messageBoxText, String caption, MessageBoxButton button) at System.Windows.MessageBox.Show(String messageBoxText) at ChatRoom.App.CurrentChannel_ShellToastNotificationReceived(Object sender, NotificationEventArgs e) at Microsoft.Phone.Notification.ShellObjectChannelInternals.OnNotificationReceived(IntPtr blob, UInt32 blobSize) at Microsoft.Phone.Notification.ShellObjectChannelInternals.ChannelHandler(UInt32 eventType, IntPtr blob1, UInt32 blobSize1, IntPtr blob2, UInt32 blobSize2) at Microsoft.Phone.Notification.HttpNotificationChannel.Dispatch(Object threadContext) at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Thre ading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() at System.Threading.ThreadPoolWorkQueue.Dispatch() at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()} System.Exception {System.UnauthorizedAccessException}

May this will help you.

private subscripeToNewChatRoom(long tempID)
            {
                ChatRoomOverview.Subscription Subscription = new ChatRoomOverview.Subscription { ContentID = Convert.ToInt32(tempID), userId = App.UserInfromationID };
         Dispatcher.BeginInvoke(() =>
                        {
        App.MobileService.GetTable<ChatRoomOverview.Subscription>().InsertAsync(Subscription);
                        });

                return null;
            }

Working Solution

private async void bwSubscription_DoWork(object sender, DoWorkEventArgs e)
{
    bool subscriped = false;
    List<object> genericlist = e.Argument as List<object>;

    var table = App.MobileService.GetTable<ChatRoomOverview.chatrooms>();
    //List<ChatRoomOverview.chatrooms> ChatRooms = table.Where(chat => chat.chatroomName == ChatroomName.Text)

    //table.InsertAsync(ChatRoom);
    ChatRoomOverview.chatrooms chat = (ChatRoomOverview.chatrooms)genericlist[0];
    //var ChatRoom = table.Where(chatting => chatting.chatroomName == chat.chatroomName).ToListAsync();

    long tempID = chat.Id;
    while (!subscriped)
    {
        try
        {
            ChatRoomOverview.Subscription Subscription = new ChatRoomOverview.Subscription { ContentID = tempID, userId = App.UserInfromationID , Notifications = 0};
            await App.MobileService.GetTable<ChatRoomOverview.Subscription>().InsertAsync(Subscription);
        }
        catch
        {

        }
        List<ChatRoomOverview.Subscription> subscript = await App.MobileService.GetTable<ChatRoomOverview.Subscription>().Where(subs => subs.ContentID == tempID && subs.userId == App.UserInfromationID && subs.Notifications == 0).ToListAsync();
        if (subscript.Count > 0)
        {
            ChatRoomOverview.userName = "";
            subscriped = true;
        }
        else
        {
            subscriped = false;
        }
    }

}

Do not attempt to display user interface elements from a background thread. The call stack clearly indicates this is what you were trying to do.

QueueUserWorkItem implies that this is a callstack from a background thread. Then we see that MessageBox.Show() is being called. This would throw the same exception in a desktop application or in an application without any contact with azure as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM