【问题标题】:Can't print out text from textbox with threads.无法从带有线程的文本框中打印出文本。
【发布时间】:2014-12-28 00:48:31
【问题描述】:

无法弄清楚如何从线程更新文本框。有任何想法吗?对不起,如果变量名和字符串是挪威语。如果有问题可以修复。 问题主要是我无法从线程内访问文本框。我是否创建单独的线程,一个用于服务器,一个用于更新 txtbox?那样的话,我该怎么做呢?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
namespace SentralGUI.Pages
{
   /// <summary>
   /// Interaction logic for Server.xaml
   /// </summary>




public partial class Server : UserControl
{
    public class Bruker
    {
        public string BrukerID { get; set; }
        public string Passord { get; set; }
        public string Forbruk { get; set; }

    }
    public class ServerStart
    {
        public List<Bruker> brukerList { get; set; }
        int n = 3;
        int n_login = 5;
        int recv, recvID, recvP;
        byte[] data = new byte[1024];
        string mottattKundeID;
        string mottattPassord;
        string consoleText = "";


        public string TxtUt()
        {

            return consoleText;

        }

        public void Start()
        {
            Socket lytteSokkel = new Socket(
                                        AddressFamily.InterNetwork,
                                        SocketType.Stream,
                                        ProtocolType.Tcp);

            IPEndPoint serverEP = new IPEndPoint(
                                        IPAddress.Parse("127.0.0.1"), 9050);

            lytteSokkel.Bind(serverEP);
            lytteSokkel.Listen(10);



            while (n-- > 0)
            {
                consoleText = "venter på en klient...";


                Socket kommSokkel = lytteSokkel.Accept(); // blokkerende 
                // metode

                IPEndPoint klientEP =
                                    (IPEndPoint)kommSokkel.RemoteEndPoint;
                consoleText = "Har forbindelse med {0} på port {1}" +
                                            klientEP.Address + serverEP.Port;


                string startup = "Login med kunde ID og passord:";
                data = Encoding.ASCII.GetBytes(startup);
                kommSokkel.Send(data, data.Length, SocketFlags.None);

                while (n_login > 0)
                {
                    kommSokkel.Send(Encoding.ASCII.GetBytes("\nBruker ID: "));

                    data = new byte[1024];
                    recvID = kommSokkel.Receive(data);
                    if (recvID == 0)
                        break;

                    mottattKundeID =
                                        Encoding.ASCII.GetString(data, 0, recvID);//her kommer input fra klient: BrukerID

                    kommSokkel.Send(Encoding.ASCII.GetBytes("Passord: "));

                    recvP = kommSokkel.Receive(data);
                    mottattPassord = Encoding.ASCII.GetString(data, 0, recvP);//her kommer input fra klient: Passord





                    bool godkjent_Login = Login(mottattKundeID, mottattPassord, brukerList);



                    if (godkjent_Login)
                    {
                        kommSokkel.Send(Encoding.ASCII.GetBytes("\nGodkjent innlogging! Trykk en tast for å få ditt forbruk.\n"));
                        string kundeForbruk = SkrivUtForbruk(mottattKundeID, brukerList);
                        kommSokkel.Send(Encoding.ASCII.GetBytes(kundeForbruk));
                        n_login = 0;
                    }
                    else kommSokkel.Send(Encoding.ASCII.GetBytes("\nBruker ID eller passord er feil! Prøv igjen."));
                }
                consoleText = "Forbindelsen med {0} er brutt " +
                                                         klientEP.Address;

                n_login = 5;
                kommSokkel.Close();
            }

            lytteSokkel.Close();


        }
        private static string SkrivUtForbruk(string kundeID, List<Bruker> bruker)
        {
            string forbrukUT = "";
            foreach (Bruker kunde in bruker)
            {
                if (kunde.BrukerID.Contains(kundeID)) forbrukUT = kunde.Forbruk;
            }

            return forbrukUT;
        }
        private static bool Login(string id, string pass, List<Bruker> bl)
        {

            bool godkjent = false;


            //var brukerLogin = new List<BrukerLogin>();
            //brukerLogin.Add(new BrukerLogin { BrukerIDInn = id , PassordInn = pass });
            foreach (Bruker kunde in bl)
            {
                if (kunde.BrukerID == id && kunde.Passord == pass) godkjent = true;
            }
            // Console.WriteLine(bl_godkjent);
            //if (brukerID_godkjent) godkjent = true;
            return godkjent;

        }


    }



    public Server()
    {
        InitializeComponent();
        txtConsol.IsEnabled = false;



    }


    private void Button_Click(object sender, RoutedEventArgs e)
    {
        btnServerStart.IsEnabled = false;

        var brukerList = new List<Bruker>();
        brukerList.Add(new Bruker { BrukerID = "13", Passord = "iamlorde", Forbruk = "6KW" });
        brukerList.Add(new Bruker { BrukerID = "14", Passord = "iamlorde", Forbruk = "5KW" });
        brukerList.Add(new Bruker { BrukerID = "15", Passord = "iamlorde", Forbruk = "63KW" });
        brukerList.Add(new Bruker { BrukerID = "16", Passord = "iamlorde", Forbruk = "71KW" });
        brukerList.Add(new Bruker { BrukerID = "17", Passord = "iamlorde", Forbruk = "1KW" });

        ServerStart objSTart = new ServerStart();
        Thread objTraad = new Thread(new ThreadStart(objSTart.Start));

        objTraad.Start();
        while (!objTraad.IsAlive)
        {
            Thread.Sleep(1000);
            string txt_ut = objSTart.TxtUt();
            TxtUt(txt_ut);
        }



    }
        public void TxtUt(string ct)
        {
            txtConsol.AppendText(ct);

        }
}
}

【问题讨论】:

  • 你不能直接从另一个线程更新 UI,我认为在 WPF 中你使用Dispatcher.Invoke
  • txtConsol 是 UI 控件吗?如果是这样,那不是没有。

标签: c# wpf multithreading tcp-ip tcpserver


【解决方案1】:

在 WPF 中,您可以使用 Dispatcher 从单独的线程对 UI 项进行更改。这是您将使用的基本形式:

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(()=>{
    yourTextBox.Text = // your value;
    Console.WriteLine(yourTextBox.Text);
}));

如果由于某种原因您不确定您是在 UI 线程上还是在单独的线程上,您可以使用 Dispatcher.CheckAccess(),如果您在 UI 线程上,它将返回 true,如果您重新在一个单独的线程上。

if (Application.Current.Dispatcher.CheckAccess()) {

请注意,DispatcherPriority 需要使用 System.Windows.Threading 命名空间。

【讨论】:

  • 我之前的答案只适用于 winforms...@furkle 有更好的答案。
  • @MikeH 谢谢,只是不想让任何人感到困惑。我确信在 WPF 中有更好的方法来做到这一点,所以请随时在这方面超越我。
  • 没问题,很高兴你提出来。我没有做太多的WPF,所以我不确定我能提供更好的答案。我错误地认为 winform 方法有效。
  • 还是有点失落,对不起!你会把它放在代码的什么地方?
  • @TomasRoaldsnes 任何你想改变 UI 元素的地方。基本上,只需包装在非 UI 线程上运行的任何代码,但会更改在 UI 线程上创建的对象,包括第一行和第四行。这更有意义吗?
【解决方案2】:

在与主线程不同的线程中运行的代码中,所有访问 ui 控件的代码都应包装在 this.Invoke(delegate() {... } ) 中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2012-11-05
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    相关资源
    最近更新 更多