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
}
}
我不知道这是正确的方式,但工作谢谢你。非常感谢。如有任何建议请来信。
消费客户端应用程序可以调用控件或表单来更新它,因此您可以在任何您喜欢的线程上引发'DataReceived'事件。
在过去,我的解决方案是让使用库的应用程序向库发送对表单的引用。库保存这些引用,并自动将所有事件包装在窗体实例的. begininvoke调用中。这样,应用程序代码就不必担心来自库的调用是否在正确的线程上。