【发布时间】:2014-06-18 19:38:46
【问题描述】:
在许多博客、教程和 MSDN 中,我可以读到从非 UI 线程访问 UI 元素是不可能的 - 好吧,我会得到一个未经授权的异常。为了测试它,我写了一个非常简单的例子:
// simple text to which TextBlock.Text is bound
private string sample = "Starting text";
public string Sample
{
get { return sample; }
set { sample = value; RaiseProperty("Sample"); }
}
private async void firstButton_Click(object sender, RoutedEventArgs e)
{
await Job(); // asynchronous heavy job
commands.Add("Element"); // back on UI thread so this should be ok?
}
private async Task Job()
{
// I'm not on UI Thread ?
await Task.Delay(2000); // some other job
Sample = "Changed"; // not ok as not UI thread?
commands.Add("Element from async"); // also not ok?
}
我有一个异步运行的Task。在那个Task 中,我想更改我的属性(这将引发PropertyChanged)并将元素添加到ObservableCollection。因为它运行async,我不应该这样做,但我没有例外,代码工作正常。因此我的怀疑和误解:
- 为什么我没有得到异常?
- 可以在
async任务中提出PropertyChanged吗? - 是否可以在
async Task中修改ObservableCollection,还是返回Task<ICollection>,得到结果后修改ObservableCollection- 清除并填写? - 我什么时候在 UI 线程的
Task中,什么时候不在? - 在上面
firstButton_Click的代码中,在awaitTask之后管理UI 元素是否可以?我总是回到 UI 线程吗?
为了进行更多测试,我将我的属性更改和集合修改放在其他线程中:
System.Threading.Timer newThreadTimer = new System.Threading.Timer((x) =>
{
Sample = "Changed"; // not UI thread - exception
commands.Add("Element from async"); // not UI thread - exception
}, null, 1000, Timeout.Infinite);
在上面的代码中,我的想法是好的——就在第一行或第二行之后,我得到了一个异常。但是第一个代码呢?我的Task在 UI 线程上运行只是运气吗?
我怀疑这是非常基本的事情和我的误解,但我需要一些澄清,因此这个问题。
【问题讨论】:
标签: c# multithreading asynchronous async-await