C# 触发OnPropertyChanged()后,Xamarin UI将在10秒内更新
一个非常奇怪的场景。。。也许有人能帮忙。这件事伤了我的头C# 触发OnPropertyChanged()后,Xamarin UI将在10秒内更新,c#,user-interface,xamarin,C#,User Interface,Xamarin,一个非常奇怪的场景。。。也许有人能帮忙。这件事伤了我的头 private string _myText = "Hello"; public string MyText { get { return _myText; } set { _myText = value; OnPropertyChanged(); //OnPropertyChanged("IsSearching"); } } 我将MyText绑定到XAM
private string _myText = "Hello";
public string MyText
{
get { return _myText; }
set
{
_myText = value;
OnPropertyChanged();
//OnPropertyChanged("IsSearching");
}
}
我将MyText绑定到XAML Xamarin视图中的标签,以调试运行此方法时发生的情况
private async void Edit_Survey_Button_OnClicked(object sender, EventArgs e)
{
MyText = "Text Before Long Method";
Stopwatch s = new Stopwatch();
await Task.Run(() =>
{
s.Start();
Task.Delay(3000).Wait();
MyText = "Text after long method" + s.ElapsedMilliseconds.ToString();
});
}
因此,当点击按钮时,文本会得到更新,令人惊讶的是,它只会在10-15秒内第二次得到更新,而本应在3秒内得到更新!我不知道为什么,我已经尝试了这么多关于如何运行这个的选项,但我想这可能与我的文本设置在不同的线程上有关
我之所以做这个测试,是因为我将进行数据下载,而不是延迟,在数据下载之后,我希望从初始状态更改一些UI元素。现在我非常怀疑如何做到这一点,希望其他人也遇到了类似的情况
________按照Sushingover的建议更新1
private void Edit_Survey_Button_OnClicked(object sender, EventArgs e)
{
IsSearching = "Method Start Edit";
Task.Run(async () =>
{
await Task.Delay(3000);
Device.BeginInvokeOnMainThread(() => { IsSearching = "Yeeeeehuuuuuuu!"; });
});
}
没有帮助 试试这个:
private async void Edit_Survey_Button_OnClicked(object sender, EventArgs e)
{
MyText = "Text Before Long Method";
Stopwatch s = new Stopwatch();
s.Start();
await Task.Delay(3000);
s.Stop();
MyText = "Text after long method" + s.ElapsedMilliseconds.ToString();
}
试试这个:
private async void Edit_Survey_Button_OnClicked(object sender, EventArgs e)
{
MyText = "Text Before Long Method";
Stopwatch s = new Stopwatch();
s.Start();
await Task.Delay(3000);
s.Stop();
MyText = "Text after long method" + s.ElapsedMilliseconds.ToString();
}
我在IOs仿真器和Android上都运行了这段代码,效果很好:
namespace Yuri1
{
public partial class Yuri1Page : ContentPage
{
async void Handle_Clicked(object sender, System.EventArgs e)
{
Stopwatch s = new Stopwatch();
await Task.Run(() =>
{
s.Start();
Task.Delay(3000).Wait();
});
MyEntry.Text="Text after long method: " + s.ElapsedMilliseconds.ToString();
}
//MyText.Text = "Text after long method" + s.ElapsedMilliseconds.ToString(); }
public Yuri1Page()
{
InitializeComponent();
}
}
}
我在IOs仿真器和Android上都运行了这段代码,效果很好:
namespace Yuri1
{
public partial class Yuri1Page : ContentPage
{
async void Handle_Clicked(object sender, System.EventArgs e)
{
Stopwatch s = new Stopwatch();
await Task.Run(() =>
{
s.Start();
Task.Delay(3000).Wait();
});
MyEntry.Text="Text after long method: " + s.ElapsedMilliseconds.ToString();
}
//MyText.Text = "Text after long method" + s.ElapsedMilliseconds.ToString(); }
public Yuri1Page()
{
InitializeComponent();
}
}
}
非常感谢参加这次讨论的每个人。因此,经过无数次尝试后,似乎最合适的解决方案是这样的。在延迟任务完成后更新UI所需的轻微延迟下,它似乎可以正常工作。在这个示例中,我调试了线程ID,还尝试了绑定x引用和数据绑定这两种类型
List<string> threads = new List<string>();
private BindableProperty IsSearchingProperty =
BindableProperty.Create("IsSearching", typeof(string), typeof(MainPage), "Hello");
public string IsSearching
{
get { return (string)GetValue(IsSearchingProperty); }
set { SetValue(IsSearchingProperty, value); }
}
public MainPage()
{
BindingContext = this;
InitializeComponent();
threads.Add(GetThreadId() + " in constructor");
}
private string GetThreadId()
{
return Thread.CurrentThread.ManagedThreadId.ToString();
}
private async void Button_OnClicked(object sender, EventArgs e)
{
threads.Add(GetThreadId() + " in method");
IsSearching = "Method Start Edit";
MyRef.Text = "Reference Text Start";
Stopwatch s = new Stopwatch();
await Task.Run( () =>
{
threads.Add(GetThreadId() + " in task");
s.Start();
Task.Delay(3000).Wait();
Device.BeginInvokeOnMainThread(() =>
{
IsSearching = "Yeeeeehuuuuuuu!";
MyRef.Text = "Reference Text End" + s.ElapsedMilliseconds.ToString(); ;
threads.Add(GetThreadId() + " in task in device begin invoke");
});
});
threads.Add(GetThreadId() + " after task");
DisplayAlert("My Threads", DiplayThreadInfo(), "Cancel");
threads = null;
}
private string DiplayThreadInfo()
{
string threadsInfo = null;
foreach (var thread in threads)
{
threadsInfo ="/"+ threadsInfo + thread + "/"+ Environment.NewLine;
}
return threadsInfo;
}
}
List threads=newlist();
私有可绑定属性是搜索属性=
创建(“IsSearching”、typeof(string)、typeof(MainPage)、“Hello”);
公共字符串正在搜索
{
get{return(string)GetValue(IsSearchingProperty);}
集合{SetValue(IsSearchingProperty,value);}
}
公共主页()
{
BindingContext=这个;
初始化组件();
Add(GetThreadId()+“在构造函数中”);
}
私有字符串GetThreadId()
{
返回Thread.CurrentThread.ManagedThreadId.ToString();
}
已单击专用异步无效按钮(对象发送方,事件参数e)
{
Add(GetThreadId()+“in方法”);
IsSearching=“方法开始编辑”;
MyRef.Text=“参考文本开始”;
秒表s=新秒表();
等待任务。运行(()=>
{
Add(GetThreadId()+“在任务中”);
s、 Start();
Task.Delay(3000.Wait();
Device.beginInvokeMainThread(()=>
{
IsSearching=“Yeeeehuuuuuuuu!”;
MyRef.Text=“Reference Text End”+s.elapsedmillisons.ToString();
Add(GetThreadId()+“在设备开始调用的任务中”);
});
});
Add(GetThreadId()+“在任务之后”);
DisplayAlert(“我的线程”,DiplayThreadInfo(),“取消”);
线程=null;
}
私有字符串DiplayThreadInfo()
{
字符串threadsInfo=null;
foreach(线程中的var线程)
{
threadsInfo=“/”+threadsInfo+thread+“/”+Environment.NewLine;
}
返回线程SINFO;
}
}
在线程调试之后,我们可以看到UI更新是在UI线程中执行的。这似乎是至关重要的,如果不这样做,问题就会开始发生。总的来说,这项工作需要semms来完成。谢谢大家。非常感谢所有参与讨论的人。因此,经过无数次尝试后,似乎最合适的解决方案是这样的。在延迟任务完成后更新UI所需的轻微延迟下,它似乎可以正常工作。在这个示例中,我调试了线程ID,还尝试了绑定x引用和数据绑定这两种类型
List<string> threads = new List<string>();
private BindableProperty IsSearchingProperty =
BindableProperty.Create("IsSearching", typeof(string), typeof(MainPage), "Hello");
public string IsSearching
{
get { return (string)GetValue(IsSearchingProperty); }
set { SetValue(IsSearchingProperty, value); }
}
public MainPage()
{
BindingContext = this;
InitializeComponent();
threads.Add(GetThreadId() + " in constructor");
}
private string GetThreadId()
{
return Thread.CurrentThread.ManagedThreadId.ToString();
}
private async void Button_OnClicked(object sender, EventArgs e)
{
threads.Add(GetThreadId() + " in method");
IsSearching = "Method Start Edit";
MyRef.Text = "Reference Text Start";
Stopwatch s = new Stopwatch();
await Task.Run( () =>
{
threads.Add(GetThreadId() + " in task");
s.Start();
Task.Delay(3000).Wait();
Device.BeginInvokeOnMainThread(() =>
{
IsSearching = "Yeeeeehuuuuuuu!";
MyRef.Text = "Reference Text End" + s.ElapsedMilliseconds.ToString(); ;
threads.Add(GetThreadId() + " in task in device begin invoke");
});
});
threads.Add(GetThreadId() + " after task");
DisplayAlert("My Threads", DiplayThreadInfo(), "Cancel");
threads = null;
}
private string DiplayThreadInfo()
{
string threadsInfo = null;
foreach (var thread in threads)
{
threadsInfo ="/"+ threadsInfo + thread + "/"+ Environment.NewLine;
}
return threadsInfo;
}
}
List threads=newlist();
私有可绑定属性是搜索属性=
创建(“IsSearching”、typeof(string)、typeof(MainPage)、“Hello”);
公共字符串正在搜索
{
get{return(string)GetValue(IsSearchingProperty);}
集合{SetValue(IsSearchingProperty,value);}
}
公共主页()
{
BindingContext=这个;
初始化组件();
Add(GetThreadId()+“在构造函数中”);
}
私有字符串GetThreadId()
{
返回Thread.CurrentThread.ManagedThreadId.ToString();
}
已单击专用异步无效按钮(对象发送方,事件参数e)
{
Add(GetThreadId()+“in方法”);
IsSearching=“方法开始编辑”;
MyRef.Text=“参考文本开始”;
秒表s=新秒表();
等待任务。运行(()=>
{
Add(GetThreadId()+“在任务中”);
s、 Start();
Task.Delay(3000.Wait();
Device.beginInvokeMainThread(()=>
{
IsSearching=“Yeeeehuuuuuuuu!”;
MyRef.Text=“Reference Text End”+s.elapsedmillisons.ToString();
Add(GetThreadId()+“在设备开始调用的任务中”);
});
});
Add(GetThreadId()+“在任务之后”);
DisplayAlert(“我的线程”,DiplayThreadInfo(),“取消”);
线程=null;
}
私有字符串DiplayThreadInfo()
{
字符串threadsInfo=null;
foreach(线程中的var线程)
{
threadsInfo=“/”+threadsInfo+thread+“/”+Environment.NewLine;
}
返回线程SINFO;
}
}
在线程调试之后,我们可以看到UI更新是在UI线程中执行的。这似乎是至关重要的,如果不这样做,问题就会开始发生。总的来说,这项工作需要semms来完成。谢谢大家。您正在使用.Wait()
同步阻塞,使用等待任务。延迟(3000)代码>取而代之。然后在TaskRun
中包装MyText
assignme