访问 UI 组件并由 Xamarin 中的另一个线程覆盖它
Accessing UI component and overwrite it by another thread in Xamarin
所以我已经尝试解决这个问题好几个小时了,我几乎要放弃了。
必须有一种方法可以访问另一个线程后面的 Xamarin C# 代码上的普通标签。
这就是我基本上在做的事情:
namespace Traktor
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TrackerPage : ContentPage
{
public delegate void TrackedTimeUpdateHandler(double elapsedTime); // Delegate to notify the TrackingPage of how much time elapsed
private TimeTracker tracker;
// Ctor, and other methods etc. are here
// ...
// Initialize the tracker and add handler to it (called in Ctor)
void Initialize()
{
tracker = new TimeTracker();
tracker.TrackedTimeUpdate += new TrackedTimeUpdateHandler(UpdateGUI);
}
// This method is called periodically by the inner thread of 'tracker'
void UpdateGUI(double elapsedTime)
{
// Status label is a label on the page this refers to
statusLabel.Text = String.Format("{0:F2}", elapsedTime);
// Throws exception: "Android.Util.AndroidRuntimeException: 'Only the original thread that created a view hierarchy can touch its views.'"
}
}
}
一个单独的线程在 TimeTracker tracker
中运行,它不断引发一个事件来通知此 TrackerPage 已用了多长时间。然后调用 UpdateGUI(...)
- 方法。那只是将 statusLabel 的文本设置为经过的时间。一切都像一个魅力。但是我无法通过 UI- 线程本身以外的另一个线程访问 statusLabel.Text
。
我已经尝试了很多,但是没有效果,这很烦人,因为主要是缺少某些东西或其他东西无法解决。例如,statusLabel 不是实现 ISynchronizeInvoke
的 Class,或者我无法使用 System.Windows.Forms.Control
- 命名空间。不知道为什么。
所以我的问题是:
有没有办法访问标签(我的 ContentPage
上 UI 的一部分)并从另一个线程修改它(或以任何方式使 elapsedTime
可以定期显示)?我不能调用,异步似乎不适合这里。我真的不知道如何解决这个问题。或者也许有一种 Xamarin 本机方法可以在 UI- 线程上调用?
到目前为止我尝试过的:
1 Best Way to Invoke Any Cross-Threaded Code?
2
3
4
-> 我不能使用 System.Windows.Forms.Control
- 命名空间。我不知道为什么。也许是因为 Xamarin 不希望我这样做。所以 System.Windows.Forms.Control.Invoke
等我无法访问。
Essentials 包含一个帮助程序 class 以强制您的代码在主 UI 线程上执行
MainThread.BeginInvokeOnMainThread(() =>
{
// Code to run on the main thread
});
所以我已经尝试解决这个问题好几个小时了,我几乎要放弃了。 必须有一种方法可以访问另一个线程后面的 Xamarin C# 代码上的普通标签。
这就是我基本上在做的事情:
namespace Traktor
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TrackerPage : ContentPage
{
public delegate void TrackedTimeUpdateHandler(double elapsedTime); // Delegate to notify the TrackingPage of how much time elapsed
private TimeTracker tracker;
// Ctor, and other methods etc. are here
// ...
// Initialize the tracker and add handler to it (called in Ctor)
void Initialize()
{
tracker = new TimeTracker();
tracker.TrackedTimeUpdate += new TrackedTimeUpdateHandler(UpdateGUI);
}
// This method is called periodically by the inner thread of 'tracker'
void UpdateGUI(double elapsedTime)
{
// Status label is a label on the page this refers to
statusLabel.Text = String.Format("{0:F2}", elapsedTime);
// Throws exception: "Android.Util.AndroidRuntimeException: 'Only the original thread that created a view hierarchy can touch its views.'"
}
}
}
一个单独的线程在 TimeTracker tracker
中运行,它不断引发一个事件来通知此 TrackerPage 已用了多长时间。然后调用 UpdateGUI(...)
- 方法。那只是将 statusLabel 的文本设置为经过的时间。一切都像一个魅力。但是我无法通过 UI- 线程本身以外的另一个线程访问 statusLabel.Text
。
我已经尝试了很多,但是没有效果,这很烦人,因为主要是缺少某些东西或其他东西无法解决。例如,statusLabel 不是实现 ISynchronizeInvoke
的 Class,或者我无法使用 System.Windows.Forms.Control
- 命名空间。不知道为什么。
所以我的问题是:
有没有办法访问标签(我的 ContentPage
上 UI 的一部分)并从另一个线程修改它(或以任何方式使 elapsedTime
可以定期显示)?我不能调用,异步似乎不适合这里。我真的不知道如何解决这个问题。或者也许有一种 Xamarin 本机方法可以在 UI- 线程上调用?
到目前为止我尝试过的:
1 Best Way to Invoke Any Cross-Threaded Code?
2
3
4
-> 我不能使用 System.Windows.Forms.Control
- 命名空间。我不知道为什么。也许是因为 Xamarin 不希望我这样做。所以 System.Windows.Forms.Control.Invoke
等我无法访问。
Essentials 包含一个帮助程序 class 以强制您的代码在主 UI 线程上执行
MainThread.BeginInvokeOnMainThread(() =>
{
// Code to run on the main thread
});