我正在为UWP开发用户控件,当某些调用发生时它会更新一些可视化元素。然而,由于核心的.NET库已经被重构,线程类也被严重削减,所以我不知道如何从用户控件的方法中识别调用线程是否是UI线程,以便确定是否使用调度程序更改一个依赖属性。
有人知道如何做到这一点吗?
编辑:调度程序在UI线程上可以“异步”地被调用,但是我真的不知道这样做是否明智——尝试通过调度程序从主线程上调用主线程。如果有人有这样做好或坏的原因,那么这也有助于回答问题。如果没有理由不在主线程上使用调度程序,那么我想就没有问题了。
我正在为UWP开发用户控件,当某些调用发生时它会更新一些可视化元素。然而,由于核心的.NET库已经被重构,线程类也被严重削减,所以我不知道如何从用户控件的方法中识别调用线程是否是UI线程,以便确定是否使用调度程序更改一个依赖属性。
有人知道如何做到这一点吗?
编辑:调度程序在UI线程上可以“异步”地被调用,但是我真的不知道这样做是否明智——尝试通过调度程序从主线程上调用主线程。如果有人有这样做好或坏的原因,那么这也有助于回答问题。如果没有理由不在主线程上使用调度程序,那么我想就没有问题了。
我已经找到了解决方案...
CoreDispatcher.HasThreadAccess 返回一个布尔值,指示您是否在UI线程上。
CoreDispatcher
可以通过CoreWindow.GetForCurrentThread().Dispatcher
进行访问。花了我一点时间才找到 :P - Felix我的儿子最近遇到了这个问题,所以我想添加一个更新的答案。
可以使用Core Dispatcher CoreWindow.GetForCurrentThread().Dispatcher
或 Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher
来访问主UI线程。
下面是一个实现Core Dispatcher
并测试调用线程是否为主UI线程的类。如果是,则调用该操作,否则调用Dispatcher.RunAsync
在主UI线程上执行它。
class Threading {
private static CoreDispatcher Dispatcher =>
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher;
public static async void ThreadSafe(DispatchedHandler action)
{
// Calls Dispatcher.RunAsync to run a method on the Main UI Thread
IAsyncAction UiThread(DispatchedHandler proc) => Dispatcher.RunAsync(CoreDispatcherPriority.Normal, proc);
// Checks to see if this was called from the Main UI thread
// If we are in the Main UI thread then Invoke the action
// Otherwise: Send it to run in the Main Ui Thread.
if (Dispatcher.HasThreadAccess) { action.Invoke(); } else { await UiThread(action); };
}
}
上述的类可如下使用:
// Some event handler callback
private void SomeCallback(object sender)(){
void line() => Frame.Navigate(typeof(PageName));
Threading.ThreadSafe(line);
}
// Pass a handle to the control and a string to update it's text property
internal static void ChangeControlText(dynamic ctrl , string v)
{
void line() {ctrl.Text= v;}
ThreadSafe(line);
}
RunAsync()
是可以的。坦白地说,在我看来,最好设计代码,以便仅从适当的线程更新属性。通常很容易保持在UI线程上,除了后台操作,将更新推回到UI线程。但如果你发现自己处于无法工作的情况下,只需调用RunAsync()
或类似方法即可。请参见我相关的抱怨:http://blogs.msmvps.com/duniho/2008/09/12/msdn-s-canonical-technique-for-using-control-invoke-is-lame/ - Peter Duniho