[英]UI Thread/Dispatcher Issue (BeginInvoke)
In a previous question I asked how to get access to UI elements in a callback thread. 在上一个问题中,我询问了如何访问回调线程中的UI元素。 I got a lot of good answers, one of which was to implement a wrapper class such as this:
我得到了很多很好的答案,其中之一是实现这样的包装器类:
public static class UIThread
{
private static readonly Dispatcher Dispatcher;
static UIThread()
{
Dispatcher = Deployment.Current.Dispatcher;
}
public static void Invoke(Action action)
{
if (Dispatcher.CheckAccess())
{
action.Invoke();
}
else
{
Dispatcher.BeginInvoke(action);
}
}
}
And you can call this using 您可以使用
UIThread.Invoke(() => TwitterPost.Text = "hello there");
However I tried extending this by calling the following in my callback function 但是我尝试通过在回调函数中调用以下内容来扩展它
UIThread.Invoke(() => loadUserController(jsonObject));
with the following method: 使用以下方法:
private void loadUserController(JObject jsonObject)
{
string profile_image_url = (string)jsonObject["profile_image_url"];
string screen_name = (string)jsonObject["screen_name"];
string name = (string)jsonObject["name"];
string location = (string)jsonObject["location"];
int statuses_count = (int)jsonObject["statuses_count"];
if (!string.IsNullOrEmpty(profile_image_url))
{
ProfileImage.Source = new BitmapImage(new Uri("blahblahbalhb.jpg", UriKind.Absolute));
}
// Set the screen name and display name if it differs
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(screen_name))
{
ScreenName.Text = screen_name;
if (!screen_name.Equals(name))
{
_Name.Text = name;
}
}
if (!string.IsNullOrEmpty(location))
{
Location.Text = location;
}
Tweets.Text = statuses_count.ToString() + " Tweets";
}
then the image will not render until another action forces a redraw (clicking a button) but the text controls will be updated. 那么该图像将不会渲染,直到另一个动作强制重绘(单击按钮),但文本控件将被更新。 If within my callback function I call setImageFile(string imageFile) which is implemented as:
如果在我的回调函数中,我将调用setImageFile(string imageFile),其实现为:
private void setImageFile(string imageFile)
{
if (this.Dispatcher.CheckAccess())
{
ProfileImage.Source = new BitmapImage(new Uri("fdsfdfdsf.jpg", UriKind.Absolute));
}
else
{
this.Dispatcher.BeginInvoke(new Action<string>(setImageFile), imageFile);
}
}
then the image will be rendered immediately. 那么图像将立即呈现。 Why is this happening?
为什么会这样呢? What properties of the Dispatcher am I not fully understanding?
我不完全了解分派器的哪些属性?
I strongly recommend that you not do this. 我强烈建议您不要这样做。
SynchronizationObject
was designed to handle this kind of scenario, along with AsyncOperation
and AsyncOperationManager
. 设计
SynchronizationObject
以及AsyncOperation
和AsyncOperationManager
来处理这种情况。
The only disadvantage to SynchronizationObject
is that there isn't the ability to test whether the code is already running on the correct thread. SynchronizationObject
的唯一缺点是无法测试代码是否已经在正确的线程上运行。 That shouldn't be a problem, since business logic code should always be aware of its thread context. 这应该不成问题,因为业务逻辑代码应始终了解其线程上下文。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.