从异步线程更新主GUI中的文本 [英] Update text in my main GUI from an async thread

查看:61
本文介绍了从异步线程更新主GUI中的文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨。



我的应用程序有一个从我的主Form类启动的Server类,它创建一个套接字(Async)监听数据的特定端口。



现在,我在检测到数据时触发的Server类上使用Asyn回调,我希望我的主GUI更新一个状态文本说收到数据,但我还没有得到如何将文本发送回主GUI的线索。



请指点?我用谷歌搜索,发现代表可能是答案,但它似乎很复杂?



谢谢



我尝试了什么:



请指点?我用谷歌搜索,发现代表可能是答案,但它似乎很复杂?



谢谢

Hi.

I have my application which has a Server class that is started from my main Form class, and it creates a socket (Async) listening to a specific port for data.

Now, I use an Asyn call back on the Server class that triggers when data is detected, and I would like my main GUI to update a status text to say "data received" but I have not got a clue how to send text back to the main GUI.

Any pointers please? I have googled and found that Delegates may be the answer but it seems so complex?

Thanks

What I have tried:

Any pointers please? I have googled and found that Delegates may be the answer but it seems so complex?

Thanks

推荐答案

.NET框架中的后台线程概念非常混乱,有时与您实际执行的操作无关。



如果我必须在今天的版本中编写这种类型的应用程序,我会选择异步/等待编程,而不是委托方式,因为,



1.代表们很难理解和正确的计划。

2.代表们还有其他事情需要处理;回调等。

3.. NET有async / await,用来代替代理和开始/结束函数的异步编程。



但是,在这种情况下,async / await的概念会更简单。因为事实上,您将把大部分异步编程留给框架本身。此外,.NET框架有几个返回任务对象的 Async 函数。我们可以使用它们并异步编程我们的应用程序。这样的事情,



The background threads concept in .NET framework is so much confusing, and sometimes irrelevant to what you might actually be doing.

If I had to write this sort of application in today's version, I would choose async/await sort of programming, instead of the delegates way, because,

1. Delegates are tough to understand and properly program.
2. Delegates have other things to be handled as well; callbacks etc.
3. .NET has async/await, that are meant to replace the asynchronous programming with delegates and begin/end functions.

However, the concept of async/await will be simpler in this case. Because of the fact, that you will leave majority of the asynchronous programming to the framework itself. Also, .NET framework has several Async functions that return Task objects. We can use them and program our apps asynchronously. Something like this,

public MainForm() {

    // Call to start the server here.
    startServer();
}

private void startServer() {
    server = new TcpListener(); // Pass your values

    // You need to rewrite this, it is just off the top of my head
    // Maybe taking this inside the listen function, and running a 
    // while(true) loop would be a better approach; but try either and chose.
    while(true) { 
        listen();
    }
}

private async void listen() { 
    // This will asynchronously listen
    var client = await server.AcceptTcpClientAsync(); 

    // Client was captured
    label.Text = "Client Connected";
    // Continue
}



我建议async / await而不是委托的原因是简单性和其他功能; 在async / await中消耗的资源较少,因为只有一个线程执行所有操作,除非您指定使用更多



哦,对了,你也可以修改这个与Socket类一起工作,我觉得TCP特定的类更简单,更方便。 :-)



TcpListener类(System.Net.Sockets) [ ^ ]



还有一件事,您不需要在此处理Dispatcher或调用,因为在async / await代码中,只有一个线程正在访问资源,因此无需将UI更新代码加载回调度程序泵。



更新



我可以想到多种方式发送和更新文本主要表单,其中两个是,



1)在表单中创建一个静态标签字段,并将其设置为您要更新的标签,然后使用来自服务器类的字段。


The reason I am suggesting async/await instead of delegates is the simplicity and other features; less resources are consumed in async/await because there is just one thread doing all unless you specify to use more.

Oh, right, you can also modify this to work with the Socket class, I feel TCP specific class to be more simpler and handier. :-)

TcpListener Class (System.Net.Sockets)[^]

One more thing, you do not need to handle the Dispatcher or invocation here, because in the async/await code, only one thread is accessing resources, thus no need to load the UI update code back to the dispatcher pump.

Update

I can think of multiple ways of sending and updating the text on the main form, two of them are,

1) Create a static label field in the form, and set that to the label which you want to update, then use that field from the server class.

public class MainForm {
    public static Label MyLabel { get; set; }

    public MainForm() {
        // Other constructor code
        MyLabel = this.label1;
    }
}

// Somewhere in the server code, 
public void listen() {
    // your server code, 
    MainForm.MyLabel.Text = "Updated text";
}

// Or you can have a separate function that updates the field, 
public void updateLabel (string message) {
    MainForm.MyLabel.Text = message;
}





2)另一种方法是将当前MainForm的引用传递给服务器类,以便服务器可以使用该对象并更新其值。这有点模棱两可,所以我不推荐,但只是让你知道,





2) The other way is to pass a reference of your current MainForm, to the server class so that server can use that object and update its values. This is somewhat ambiguous approach so I will not recommend, but just so that you know,

public class Server {
    public static MainFrom parentForm { get; set; } // Can be instance as well
    public Server(MainForm referenceForm) {
       parentForm = referenceForm;
    }

    // Then update
    public void updateField(string message) {
        parentForm.label1.Text = message;
    }
}





当然,你也可以采取其他方式。它们都非常相似,您需要传递引用然后通过该引用。



And of course, you can have other ways as well. They all work quite similar, you need to pass the reference and then through that reference.


这篇关于从异步线程更新主GUI中的文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆