如何使用数据Socket类接收事件? [英] How to use data receive event in Socket class?

查看:178
本文介绍了如何使用数据Socket类接收事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经写了使用的TcpClient在dotnet的沟通一个简单的客户端。为了等待数据信息从服务器我使用的是阅读()线程使用阻塞阅读()呼吁插座。当我收到东西我一定要产生各种事件。这些事件发生在工作线程,因此你不能直接更新UI。 的invoke()可以使用,但对最终开发了困难,因为我的SDK将使用的所有或使用presentation框架谁可以不使用的用户界面的用户。 presentation框架有处理这种不同的方式。 的invoke()在我们的测试应用程序,如Microstation的加载项采取了很多的时间在那一刻。 Microstation的是单线程应用程序,并调用调用它的线程是不好的,因为它总是忙于绘画和其他的东西的信息需要很长时间来处理。

I have wrote a simple client that use TcpClient in dotnet to communicate. In order to wait for data messages from server i use a Read() thread that use blocking Read() call on socket. When i receive something i have to generate various events. These event occur in the worker thread and thus you cannot update a UI from it directly. Invoke() can be use but for end developer its difficult as my SDK would be use by users who may not use UI at all or use Presentation Framework. Presentation framework have different way of handling this. Invoke() on our test app as Microstation Addin take a lot of time at the moment. Microstation is single threaded application and call invoke on its thread is not good as it is always busy doing drawing and other stuff message take too long to process.

我希望我的事件产生相同的线程的用户界面使用户DONOT必须要经过调度调用

I want my events to generate in same thread as UI so user donot have to go through the Dispatcher or Invoke.

现在我想知道我怎样才能通过套接字通知时,数据到达?是否有一个内置的回调为。我喜欢的风格的Winsock接收事件,而不使用单独的读线程。我也不想用窗口计时器来轮询数据。

Now i want to know how can i be notified by socket when data arrive? Is there a build in callback for that. I like winsock style receive event without use of separate read thread. I also do not want to use window timer to for polling for data.

我发现的IOControl code.AsyncIO 标志的IOControl()功能,帮助说。

I found IOControlCode.AsyncIO flag in IOControl() function which help says

启用通知时,数据是   等待接收。这个值是   等于Winsock 2 FIOASYNC   恒定的。

Enable notification for when data is waiting to be received. This value is equal to the Winsock 2 FIOASYNC constant.

我无法找到如何使用它来获得通知的任何实例。如果我是正确的MFC / Winsock的,我们要创建的尺寸(0,0)这只是用于监听数据接收事件或其他套接字事件的窗口。但我不知道该怎么做,在dotnet的应用程序。

I could not found any example on how to use it to get notification. If i am right in MFC/Winsock we have to create a window of size(0,0) which was just used for listening for the data receive event or other socket events. But i don't know how to do that in dotnet application.

推荐答案

好吧,我得到它运行起来。我真的找是如何无缝地发布事件UI线程。在其中创建我的连接。之后前往掷框架codeI想出了下面的概念证明。 的SynchronizationContext 可以使用我的组件绑定到创建它的UI线程。比我可以发布事件到主UI线程,这样用户就不必做调用

Ok I got it up and running. What i was really looking was how to seamlessly post event to UI thread. in which my connection is created. After going throw framework code i came up with following proof of concept. SynchronizationContext can be use to bind my component to the UI thread that creates it. And than i can post events to to main UI thread so user don't have to do Invoke.

在下面的例子中,我创建一个 ThreadUISa​​feTimer 它使用单独的线程,就像使用一个用于读取和筹款活动我的套接字客户端。现在,在这种情况下,使用的SynchronizationContext 发布事件,如果有可能,否则使用工作线程提高活动。

In following example i created a ThreadUISafeTimer which use seperate thread just like my socket client that use one for reading and raising events. Now In this case it use SynchronizationContext to post event if possible otherwise it raise event using the worker thread.

[DefaultEvent(嘀)     公共类ThreadUISa​​feTimer:组件     {         私人const int的真= 1;         私人const int的假= 0;         私人诠释启用=假;         私人的SynchronizationContext上下文;

[DefaultEvent("Tick")] public class ThreadUISafeTimer : Component { private const int True = 1; private const int False = 0; private int enabled = False; private SynchronizationContext context;

    public event EventHandler Tick = delegate { };

    [DefaultValue(false)]
    public ushort Interval { get; set; }

    public ThreadUISafeTimer() {
        Interval = 100;
        this.Events.AddHandler("Tick", Tick);
        //If this class is created by a UI thread it will always post the Tick event to it.
        //otherwise it would be null and Tick would occure in seperate thread.
        context = SynchronizationContext.Current;

    }
    protected override bool CanRaiseEvents {
        get {
            return true;
        }
    }
    [DefaultValue(false)]
    public bool Enabled {
        get {
            return enabled == True;
        }
        set {
            int newval = value ? True : False;
            if (enabled != newval) {
                if (newval == False)
                    Thread.VolatileWrite(ref enabled, False);
                else {
                    enabled = True;
                    ThreadPool.QueueUserWorkItem(
                        new WaitCallback(delegate(object o) {
                        try {
                            do {
                                try {
                                    Thread.Sleep(Interval);
                                    if (Thread.VolatileRead(ref enabled) == True) {
                                        var callback = new SendOrPostCallback(delegate(object arg) {
                                            try {
                                                Tick(this, EventArgs.Empty);
                                            }
                                            catch (Exception exp) {
                                                Application.OnThreadException(exp);
                                                return;
                                            }
                                        });
                                        //If context null raise Tick event from current thread
                                        if (context == null)
                                            callback(null);
                                        else
                                            //otherwise post it to the UI thread that own this timer.
                                            context.Post(callback, null);
                                    }
                                }
                                catch (ThreadInterruptedException) {
                                }

                            } while (Thread.VolatileRead(ref enabled) == True);
                        }
                        catch (ThreadAbortException) {
                        }
                    }), null);
                }
            }
        }
    }

这篇关于如何使用数据Socket类接收事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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