这是我正在使用的UserControl
。
this.CardHolderName.Content是用户控件的UI中的label
。
public partial class PersonCredential : UserControl
{
public PersonCredential()
{
InitializeComponent();
Dispatcher.BeginInvoke( (Action) (() => {
SCLib type = new SCLib();
type.StartMonitoring();
type.CardArrived += (string ATR) => { this.CardHolderName.Content = ATR; };
};
}));
我仍然收到错误,“ 调用线程无法访问此对象,因为其他线程拥有它 ”,即使我使用的是Dispatcher.BeginInvoke
。
使用Dispatcher
的方式有问题吗?
}
编辑: 我在内容控件中实例化用户控件,代码隐藏是:
public partial class MainWindow : Window
{
PersonCredential personCredential {get;set;}
public MainWindow()
{
InitializeComponent();
var personCredential = new CoffeeShop.PersonCredential();
//create an instance of user control.
this.personCredentials.Content = personCredential;
// assign it to the content control inside the wpf main window
.. // blah blah
}
编辑1:
启动监控代码:
public async void StartMonitoring()
{
// Wait for user to press a key
try
{
this.establishContext();
await Task.Run(new Action(WaitForReaderArrival));
////WaitForReaderArrival();
if (IsReaderArrived())
答案 0 :(得分:4)
编辑。 StartMonitoring
已经监视另一个线程。关键是没有从UI线程中引发CardArrived
事件:
public PersonCredential()
{
InitializeComponent();
SCLib type = new SCLib();
type.StartMonitoring();
type.CardArrived += (string ATR) => {
// when card arrives, dispatch back to UI thread
Dispatcher.BeginInvoke(new Action(() => {
this.CardHolderName.Content = ATR;
}));
};
}
如果您使用的是.NET 4或更高版本,请使用Task.Factory.StartNew()
代替new Thread()
。
答案 1 :(得分:1)
如果IsReaderArrived
检查是即时非阻塞调用(即完成时间不到50毫秒),我建议使用{{1}在调用者的线程上启动轮询循环}:
Task.Delay(interval)
这是一个异步循环。如果从UI线程调用public async Task StartMonitoring(int interval, CancellationToken token)
{
this.establishContext();
while (true)
{
token.ThrowIfCancellationRequested();
if (IsReaderArrived())
{
// make sure to reset the flag inside IsReaderArrived
// so the event won't be fired upon the next iteration
if (this.CardArrived != null)
this.CardArrived(this, EventArgs.Empty);
}
await Task.Delay(interval);
}
}
,则StartMonitoring
事件将在同一UI线程上触发,代码的客户端将不必担心CardArrived
。如果您需要解释如何发生这种情况,请阅读"It's All About the SynchronizationContext."