无效的跨线程访问。错误 [英] Invalid cross-thread access. error

查看:319
本文介绍了无效的跨线程访问。错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在silverlight中有一个网络表单。

I have a web form in silverlight.

在某些按钮的操作点击我想更新另一个控件,如图表,Textbox等

On action of some button click i want to update a another control like chart, Textbox etc

在填充图表或文本框的同时,我需要显示一个繁忙指示符。

In the mean time when it fills the chart or textbox, i need to show a busy indicator


  1. 繁忙指示器应显示在屏幕中第一个

  2. 图表值后面应显示更新

  3. 图表值将反映在屏幕中

  4. 忙碌指标应该隐藏

  1. Busy indicator should show first in screen
  2. behind the chart value should get update
  3. Chart value will reflect in screen
  4. Busy indicator should hide

但是问题是当我尝试使用Thread我收到一个错误无效的跨线程访问。。因为线程正在访问
的UI控件。我尝试的4个步骤如下。

But the problem is when i try using Thread I am getting an error "Invalid cross-thread access.". As the thread is accessing the UI control. The 4 steps which i have tried is as follows.

任何有价值的建议如何解决这个问题。

Any valuable suggestion how to solve this issue.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using System.ComponentModel;
using System.Windows.Threading;


namespace SilverlightApplication2
{
  public partial class MainPage : UserControl
    {

        public MainPage()
        {
            InitializeComponent();



        }

        private void test1()
        {


            for (int i = 1; i < 10000; i++)
            {
                System.Diagnostics.Debug.WriteLine(i.ToString());
            }
        textbox1.Text="test";   //=> Throwing Error "Invalid cross-thread access."
            busyIndicator1.IsBusy = false;   //=> Throwing Error "Invalid cross-thread access."
        }



     private void button1_Click(object sender, RoutedEventArgs e)
         {
             busyIndicator1.IsBusy = true;

             Thread th1 = new Thread(test1);
             th1.Start();

         }

    }
}



< h2> step 2 =>尝试BackgroundWorker

step 2 => Tried BackgroundWorker

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using System.ComponentModel;
using System.Windows.Threading;


namespace SilverlightApplication2
{
  public partial class MainPage : UserControl
    {

        public MainPage()
        {
            InitializeComponent();



        }

        private void test1()
        {


            for (int i = 1; i < 10000; i++)
            {
                System.Diagnostics.Debug.WriteLine(i.ToString());
            }
        textbox1.Text="test";   //=> Throwing Error "Invalid cross-thread access."
            busyIndicator1.IsBusy = false;   //=> Throwing Error "Invalid cross-thread access."
        }



     private void button1_Click(object sender, RoutedEventArgs e)
         {
             busyIndicator1.IsBusy = true;

            var bw = new BackgroundWorker();
            bw.DoWork += (s, args) =>
            {
                test1();  //Stuff that takes some time
            };
            bw.RunWorkerCompleted += (s, args) =>
            {
                busyIndicator1.IsBusy = false;
            };
            bw.RunWorkerAsync();              
         }

    }
}



步骤3 =>试图从后面的代码中触发事件



Step 3 => Tried to raise an Event from the code behind

public delegate void LinkToEventHandler();
public static event LinkToEventHandler Evt;

 private void button1_Click(object sender, RoutedEventArgs e)
 {
     busyIndicator1.IsBusy = true;

     Evt += new LinkToEventHandler(this.test1);
     Evt();
 }



private void test1()
{


    for (int i = 1; i < 10000; i++)
    {
        System.Diagnostics.Debug.WriteLine(i.ToString());
    }
    textbox1.Text="test";   //=> Throwing Error "Invalid cross-thread access."
    busyIndicator1.IsBusy = false;   //=> Throwing Error "Invalid cross-thread access."
}



步骤4 =>尝试绑定Busyindicator



step 4 => Tried Binding the Busyindicator

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using System.ComponentModel;
using System.Windows.Threading;


namespace SilverlightApplication2
{
    public partial class MainPage : INotifyPropertyChanged
    {
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
        public const string IsBusyPropertyName = "busyIndicator1";
        private bool _isBusy = false;
        public bool IsBusy
        {
            get
            {
                return _isBusy;
            }
            set
            {
                if (_isBusy != value)
                {
                    _isBusy = value;
                    RaisePropertyChanged(IsBusyPropertyName);
                }
            }
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
            if ((propertyChanged != null))
            {
                propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }


        private void button1_Click(object sender, RoutedEventArgs e)
        {

            IsBusy = true;

            test1();

            IsBusy=false;

        }

    }


    public partial class MainPage : UserControl
    {

        public MainPage()
        {
            InitializeComponent();



        }


        private void test1()
        {


            for (int i = 1; i < 10000; i++)
            {
                System.Diagnostics.Debug.WriteLine(i.ToString());
            }


        }



    }
}

注意: - 我想要一个解决方案,应该在Silverlight中以Web形式工作,而不是窗体

Note:- I want a solution which should work in Web form in silverlight not the windows form

推荐答案

这应该适合你。基本上将你的处理代码放在一个线程中,并通过Dispatcher返回你的UI控件

This should work for you. Essentially place your processing code in a thread and get back your UI control via a Dispatcher

 public partial class MainPage : UserControl
    {
        private Thread _thread1;

        public MainPage()
        {
            InitializeComponent();
        }

        private void StartThreads()
        {
            _thread1 = new Thread(test1);
            _thread1.Start();
        }
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            busyIndicator1.IsBusy = true;
            StartThreads();
        }

        private void test1()
        {
            for (int i = 1; i < 10000; i++)
            {
                System.Diagnostics.Debug.WriteLine(i.ToString());
            }
            this.Dispatcher.BeginInvoke(delegate()
            {
                textBox1.Text = "test";
                busyIndicator1.IsBusy = false;
            });
        }
    }

这篇关于无效的跨线程访问。错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆