0

BeginInvoke()を使用すると、ArgumentExceptionとTargetParameterCountExceptionが発生します。

1)最初の呼び出しで、System.ArgumentExceptionが発生します。「System.String」タイプのオブジェクトを「System.Object[]」タイプに変換することはできません。

2)2回目の呼び出しで、Gives TargetParameterCountException:{"パラメーター数の不一致"}が発生します。

なぜそれが起こるのですか?

using System;
using System.Threading;
using System.Windows.Forms;

namespace BeginInvokeArgsTest
{
    public partial class Form1 : Form
    {
        private delegate void VoidDelegate(params object[] args);

        private Delegate methodDelegate;

        public Form1()
        {
            InitializeComponent();

            methodDelegate = new VoidDelegate(SetLabelDelegate);

            Thread t = new Thread(ChangeDay);
            t.Start();
        }

        private void ChangeDay()
        {
            //Gives ArgumentException. 'System.String' cannot be converted to type 'System.Object[]'.
            ChangeDay(new VoidDelegate(SetLabelDelegate), "Sunday" );

            //Gives TargetParameterCountException: {"Parameter count mismatch."}
            ChangeDay(new VoidDelegate(SetLabelDelegate), "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
        }


        private void ChangeDay(Delegate del, params object[] args)
        {
            if (this.InvokeRequired)
            {
                methodDelegate = del;
                this.BeginInvoke(new VoidDelegate(RouterDelegate), args );
            }
        }

        private void RouterDelegate(params object[] args)
        {
            methodDelegate.DynamicInvoke(args);
        }

        private void SetLabelDelegate(params object[] args)
        {
            foreach (object day in args)
            {
                label1.Text = day as string;
                Thread.Sleep(1000);
            }            
        }
    }
}

PS:間違って組み立てられた質問を修正しました。古い間違って組み立てられた質問について心からお詫び申し上げます。私は通常、これほど不注意ではありません。言語構文エラーがある場合は、それも無視してください。

4

1 に答える 1

1

わかりました...より完全な例を使用すると、何が起こっているのかを簡単に確認できます。

問題は、デリゲートがオブジェクト配列でなければならない単一のパラメーターを予期していることです。

次に、それをどのように呼び出しているかを見てください。

private void ChangeDay(Delegate del, params object[] args)
{
    if (this.InvokeRequired)
    {
        methodDelegate = del;
        this.BeginInvoke(new VoidDelegate(RouterDelegate), args);
    }
}

ここでは、引数argsの配列が期待されます...それらの複数。したがって、デリゲートが2つの文字列パラメーターを受け取った場合、長さは2になり、各要素は文字列参照になります。object[]

したがって、必要なobject[]長さ1のwithであり、その唯一の要素は別の要素への参照object[]です。あなたはそれを簡単に行うことができます:

this.BeginInvoke(new VoidDelegate(RouterDelegate), new object[] { args });

と同じことRouterDelegate

methodDelegate.DynamicInvoke(new object[] { args });

その時点で、すべてが正常に機能すると思います(デリゲートの呼び出しに関しては、UIスレッドでスリープするべきではありませんが、それは別の問題です)。

于 2012-12-14T07:05:50.493 に答える