[英]UI Frozen / Tried to work with task / async await
我编写了一个WPF
程序来读取PC的配置。
必须刷新Programm, HttpWebRequest
将延迟代码,因此UI将冻结。
我尝试使用async
/ await
task
s。
Class
网络中的方法:
public TreeView CreatTVURLs()
{
TreeView TVURLs = new TreeView(); //Here it will break. Says no STA-Thread
List<CPingables> lURLs = new List<CPingables>();
lURLs = ReadURLsFromFile();
TVURLs.Name = "URLs";
TVURLs.Background = System.Windows.Media.Brushes.Transparent;
TVURLs.BorderThickness = new Thickness(0);
foreach (CPingables item in lURLs)
{
tviURL.Items.Add("IP:\t\t\t" + item.IP.ToString());
tviURL.Items.Add("URL:\t\t\t" + item.URL);
... more stuff
尝试使用Thread
: MainWindow
代码:
public async void openWindow()
{
TreeView tvURLs = new TreeView();
tvURLs = (TreeView) TreeViewTest();
//tvURLs = Network.CreatTVURLs();
StackPanel.Children.Add(tvURLs);
}
private TreeView TreeViewTest()
{
TreeView tvURLs = new TreeView();
Thread t = new Thread(() => { tvURLs = Network.CreatTVURLs(); });
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
return tvURLs;
}
尝试过的Task
:
public async void openWindow()
{
TreeView tvURLs = new TreeView();
tvURLs = (TreeView) await TreeViewTest();
Task.WaitAll();
StackPanel.Children.Add(tvURLs);
}
private Task<TreeView> TreeViewTest()
{
TreeView tv = new TreeView();
return Task.Factory.StartNew(() => { tv=(TreeView)Network.CreatTVURLs()});
}
我总是说必须要有一个STA Thread才能处理Form
项。
编辑:
HttpWebRequest
public async void pingIP()
{
try
{
if (_IPPingAvailible == true)
{
Ping pinger = new Ping();
PingReply replyIP = pinger.Send(_IP);
_PingByIP = replyIP.Status == IPStatus.Success;
}
}
catch (Exception)
{
_PingByIP = false;
}
try
{
if (_UrlAvailible == true)
{
var uriBuilder = new UriBuilder(_URL);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uriBuilder.Uri);
request.Timeout = 1000;
using (var response = await request.GetResponseAsync() as HttpWebResponse)
{
if (response != null && response.StatusCode == HttpStatusCode.OK)
{
_ReachableByHttp = true;
}
else
{
_ReachableByHttp = false;
}
}
}
}
catch
{
_ReachableByHttp = false;
}
}
规则是,您只能在UI线程(也称为Dispatcher线程,或主线程)中访问UI元素。 您正在违反此规则。 您可以通过以下方式Task.Factory.StartNew(...)
新线程: Task.Factory.StartNew(...)
resp by new Thread(...);
,但是您正在操纵新线程内的UI元素(treeview)。
相反,您应该仅在新线程中执行I / O操作或HttpRequest / Response,但是其他所有操作(例如,从http响应数据创建树视图)都应在UI线程中完成。
public async void openWindow()
{
TreeView tvURLs = await Network.CreatTVURLsAsync();
StackPanel.Children.Add(tvURLs);
}
public async Task<TreeView> CreatTVURLsAsync()
{
//you are in dispatcher thread here, so you can access UI elements here
TreeView TVURLs = new TreeView();
TVURLs.Name = "URLs";
TVURLs.Background = System.Windows.Media.Brushes.Transparent;
TVURLs.BorderThickness = new Thickness(0);
List<CPingables> lURLs = null;
await Task.Run(() =>
{
//you are in new thread now, so you cannot access UI elements here
lURL = ReadURLsFromFile();
});
//you are in dispatcher thread again, so you can access UI elements again
foreach (CPingables item in lURLs)
{
var tviURL = new TreeViewItem();
..more stuff
TVURLs.Items.Add(tviURL);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.