我正在创建一个带有客户端套接字和捕获数据的库(Async)。我知道当UI使用这个库需要保存线程处理时,如果有一种方法可以在库中处理这个问题并释放UI以进行保存线程处理,那么我就会徘徊。
我正在做的是在接收数据时创建一个事件,但是这个新事件在与UI不同的线程中运行,因此这将产生" Crossover威胁问题"所以我需要在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
}
}
我不知道这是不是正确的方法,但是正在工作,谢谢你。非常感谢你。任何消化都请写。
答案 0 :(得分:0)
使用客户端应用程序可以在控件或表单上调用以对其进行更新,因此您只需提升“DataReceived”即可。任何您喜欢的主题上的事件。
答案 1 :(得分:0)
我过去的解决方案是使用库将应用程序的引用发送到库中。该库保存此引用并自动将所有事件包装在该表单实例上的.BeginInvoke调用中。这样,应用程序代码就不必担心确保来自库的调用是在正确的线程上。