c# GUI和异步客户端套接字

本文关键字:客户端 套接字 异步 GUI | 更新日期: 2023-09-27 18:16:23

我正在创建一个带有客户端套接字和捕获数据(异步)的库。我知道当UI使用这个库时需要保存线程处理,所以我在想是否有一种方法可以在库中处理这个问题,并将UI从必须进行保存线程处理中解放出来。

当我收到数据时,我正在做的是创建一个事件,但是这个新事件运行在与UI不同的线程中,因此这将创建"交叉威胁问题",因此我需要在UI中进行保存线程处理。但是,使用我的库的所有UI都必须对所有组件执行相同的保存线程处理?

..........................这是Bradley Uffner和Ananke Ideas的新方法:

public class ClientControler
{   
    private ClientSocket Client { get; set; }
    private Form Main { get; set; }
    public event EventHandler<DataReceivedEventArgs> DataReceived;
    public event EventHandler<DataReceivedEventArgs> Received;
    protected virtual void ReceivedCall(string name, int number)
    {
        if (Received != null)
        {
            Received(this, new DataReceivedEventArgs(name, number));
        }
    }
    public ClientControler(Form main)
    {
        Main = main;
        Client = new ClientSocket("127.0.0.1", 8080);
        // (1) this is when the socket send the data
        Client.DataReceived += OnReceived;
        Client.Connect();
        // (4) DataReceived delegate has OnUpdated asigned and then call
        DataReceived = new EventHandler<DataReceivedEventArgs>(OnUpdated); 
    }
    // (2) the socket data is received here
    public void OnReceived(object sender, DataReceivedEventArgs e)
    {
        // (3) Main Form Invoke DataReceived delegate
        Main.Invoke(DataReceived, this, e);
    }
    // (5) OnUpdated is called in the same thread of the Main Form
    public void OnUpdated(object sender, DataReceivedEventArgs e)
    {
        ReceivedCall(e.name, e.number);// (6) Event launch
    }
}
public partial class Form1 : Form
{
    private ClientControler Control { get; set; }

    public Form1()
    {
        InitializeComponent();
        Control = new ClientControler(this);//Connecting the socket
        Control.Received += OnReceived;//Waiting for the Event
    }
    public void OnReceived(object sender, DataReceivedEventArgs e)
    {
        /*
        This is where the problem was before, 
        normaly I had to code save thread here but now is just working.
        */
        label1.Text = e.name;
        label2.Text = e.number.ToString();
        Log("Viewer", "Client", "Received", e.name);//this method just add 
        //a log to a listbox where you have to code save thread too,
        //without this solution
    }
}

我不知道这是正确的方式,但工作谢谢你。非常感谢。如有任何建议请来信。

c# GUI和异步客户端套接字

消费客户端应用程序可以调用控件或表单来更新它,因此您可以在任何您喜欢的线程上引发'DataReceived'事件。

在过去,我的解决方案是让使用库的应用程序向库发送对表单的引用。库保存这些引用,并自动将所有事件包装在窗体实例的. begininvoke调用中。这样,应用程序代码就不必担心来自库的调用是否在正确的线程上。