繁体   English   中英

UI冻结/尝试与任务一起使用/异步等待

[英]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

尝试使用ThreadMainWindow代码:

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM