Вызовите () и BeginInvoke () ведущий себя по-другому при выполнении переопределяемого метода через делегата

Хотя я до сих пор не нашел решения проблемы с драйвером calcite-core, мне удалось найти другой способ выполнить jar.

Я добавил следующие два плагина к своему pom.xml. maven-dependency-plugin копирует все соответствующие файлы зависимостей в папку lib, а maven-jar-plugin создает один исполняемый файл JAR.

                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <configuration>
                    <outputDirectory>${project.build.directory}/lib</outputDirectory>
                    <excludeTransitive>false</excludeTransitive>
                    <stripVersion>false</stripVersion>
                </configuration>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.4</version>
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <classpathPrefix>lib/</classpathPrefix>
                            <mainClass>com.example.MainClass</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>

Примечание. Добавление <mainClass>com.example.MainClass</mainClass> поможет manifest.mf понять, что такое основной класс.

7
задан Joel Coehoorn 19 November 2008 в 18:14
поделиться

3 ответа

У меня еще нет ответа, но я имею то, чему я верю, чтобы быть немного более четкой программой для демонстрации причуды:

using System;

delegate void MyDelegate();

public class Program
{
    static void Main(string[] args)
    {
        var c = new MyChild();
        c.DisplayOddity();
        Console.ReadLine();
    }
}

public class MyParent
{
    public virtual void X()
    {
        Console.WriteLine("Executing MyParent.X");
    }
}

public class MyChild : MyParent
{
    public void DisplayOddity()
    {
        MyDelegate md = base.X;

        Console.WriteLine("Calling Invoke()");
        md.Invoke();                // Executes base method... fair enough

        Console.WriteLine("Calling BeginInvoke()");
        md.BeginInvoke(null, null); // Executes overridden method!
    }

    public override void X()
    {
        Console.WriteLine("Executing MyChild.X");
    }
}

Это не включает рекурсивных вызовов. Результатом является все еще та же причуда хотя:

Calling Invoke()
Executing MyParent.X
Calling BeginInvoke()
Executing MyChild.X

(Если Вы соглашаетесь, что это - более простая репродукция, не стесняйтесь заменять код в исходном вопросе, и я удалю его из своего ответа :)

Честно говоря, это похоже на ошибку мне. Я вырою вокруг немного больше.

5
ответ дан 7 December 2019 в 10:10
поделиться

В то время как Делегат. Вызовите называет метод делегата непосредственно, Делегата. BeginInvoke внутренне использует ThreadPool. QueueUserWorkItem (). md. Вызовите (), только смог назвать основу. X, потому что методы базового класса доступны в производном классе через основное ключевое слово. Так как делегат, запущенный пулом потоков, является внешним к Вашему классу, ссылка на ее X методов подвергается перегрузке, точно так же, как код ниже.



    public class Program
    {
        static void Main(string[] args)
        {
            MyChild a = new MyChild();
            MyDelegate ma = new MyDelegate(a.X);

            MyParent b = new MyChild();
            MyDelegate mb = new MyDelegate(b.X);

            ma.Invoke();
            mb.Invoke();
            ma.BeginInvoke(CallBack, null);
            mb.BeginInvoke(CallBack, null); //all four calls call derived MyChild.X

            Console.ReadLine();
        }

        public static void CallBack(IAsyncResult iAsyncResult)
        {
            return;
        }
    }

Отладка в код Платформы.NET: http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx

1
ответ дан 7 December 2019 в 10:10
поделиться

Возможно, не ответ, который Вы ищете, но это, кажется, работает:

ThreadPool.QueueUserWorkItem(x => md());

или

new Thread(() => md()).Start();

Но необходимо будет сделать собственный учет :(

0
ответ дан 7 December 2019 в 10:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: