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

时间:2015-10-07 14:53:02

标签: c# multithreading winforms sockets asynchronous

我正在创建一个带有客户端套接字和捕获数据的库(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
    }
}

我不知道这是不是正确的方法,但是正在工作,谢谢你。非常感谢你。任何消化都请写。

2 个答案:

答案 0 :(得分:0)

使用客户端应用程序可以在控件或表单上调用以对其进行更新,因此您只需提升“DataReceived”即可。任何您喜欢的主题上的事件。

答案 1 :(得分:0)

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