简体   繁体   English

C#从静态类调用委托

[英]C# Invoke delegate from static class

I've a static class called Service which starts a new thread to keep listening message from other process. 我有一个称为Service的静态类,它将启动一个新线程以保持侦听其他进程的消息。 In this class I manage a list of delegates which needs to be invoked when a message is received. 在此类中,我管理代表列表,当收到消息时需要调用这些代表。 Some of the methods of these delegates need to run in the main thread. 这些委托的某些方法需要在主线程中运行。

If I would create the threat in some form, for example, I could just do 例如,如果我以某种形式制造威胁,我可以

this.Invoke(@delegate, new object[] { messageReceived });

But I can't do that because I'm in a static class. 但是我不能这样做,因为我在静态课程中。 So I tried doing like this: 所以我尝试这样做:

@delegate.Invoke(messageReceived);

But it doesn't work because it doesn't change the subprocess where the method is executed (it is executed from my created threat, not from the main one). 但这是行不通的,因为它不会更改执行该方法的子进程(它是从我创建的威胁中执行的,而不是从主要威胁中执行的)。

How can I do? 我能怎么做?

Thanks! 谢谢!

Modify your static class to accept a parameter. 修改您的static类以接受参数。

Pass your this variable as a parameter to your static class. this变量作为参数传递给static类。

Why you don't use the System.Threading.SynchronizationContext class? 为什么不使用System.Threading.SynchronizationContext类? If you are going to move in the future in WPF is good to learn this. 如果将来要使用WPF迁移,最好学习一下。 Synchronization context is the standard portable method to deal with interthreading messages. 同步上下文是处理线程间消息的标准可移植方法。 There is a version for each system... from System.Web, windows forms, wpf and also custom synchronization context. 每个系统都有一个版本... System.Web,Windows窗体,wpf和自定义同步上下文都有。

public static class MyClass
{
    public static void MyFunction(MyObject messageReceived )
    {
        // Call this stuff from non-gui thread.

        SynchronizationContext syncContext = SynchronizationContext.Current;
        syncContext.Send(MyMethod, param);

        // You can also use SyncContext.Post if you don't need to wait for completion.
        syncContext.Post(MyMethod, param);
    }

    private static void MyMethod(object state)
    {
        MyObject myObject = state as MyObject;
        ... do my stuff into the gui thread.
    }

    // Using anonymous delegates you can also have a return value using Send.
    public static int MyFunctionWithReturnValue(MyObject parameter)
    {
        int result = 0;
        SynchronizationContext.Current.Post(delegate (object p)
        {
            result = parameter.DoSomething()
        }, null);

        return result;
    }
}

Your issue can be addressed through SynchronizationContext . 您的问题可以通过SynchronizationContext解决。 In nutshell, capture the SynchronizationContext of UI thread and use Post method to post item on the GUI message loop. 简而言之,捕获UI线程的SynchronizationContext并使用Post方法在GUI消息循环上发布项目。 Needless to write more since you can find an excellent article Here 无需多写,因为您可以在这里找到出色的文章

Sorry I forgot it in my question. 对不起,我在提问中忘了它。 I also wanted to avoid using System.Windows.Forms classes in my static class. 我还想避免在我的静态类中使用System.Windows.Forms类。

The easiest way I found is to call Invoke method from the delegate object (as I tried before and it didn't work). 我发现最简单的方法是从委托对象中调用Invoke方法(就像我之前尝试过的那样,它没有用)。 And in the method of the delegate do this: 并在委托的方法中执行以下操作:

if (this.InvokeRequired)
    this.Invoke(MethodWhichDoesRealStuff, new object[] { message });
else
    MethodWhichDoesRealStuff(message);

I've also noticed that I actually didn't have to manage the delegate list in my class. 我还注意到实际上我不必在班上管理委托人列表。 An event does exactly that for me. 一个事件确实为我做到了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM