无效的跨线程访问。错误 [英] Invalid cross-thread access. error
问题描述
我在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
- 繁忙指示器应显示在屏幕中第一个
- 图表值后面应显示更新
- 图表值将反映在屏幕中
- 忙碌指标应该隐藏
- Busy indicator should show first in screen
- behind the chart value should get update
- Chart value will reflect in screen
- 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屋!