0

我正在尝试在后台工作进程上做一些工作,当工作完成时,我想显示一个模式对话框。我的代码可以很好地用于一个简单的 Action 委托,但希望能够传入一个 Func 委托并获得一个返回类型。到目前为止,我有一个带有方法的表格

    public void ShowDialogWhile(Action work)
    {
        _work = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();
    }

我接下来想要工作的是

    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        _workWithReturn = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();

        return (TResult)Result;
    }

到目前为止我还没有运气,因为我在声明我的 _workWithReturn 的类型时一直摔倒

        Func<TResult> _workWithReturn;

有人有想法吗?

这是完整的代码。

public partial class AsyncWaitDialog : Form, IAsyncDialog
{
    BackgroundWorker _worker = new BackgroundWorker();
    Action _work;
    Func<TResult> _workWithReturn;
    public object Result { get; private set; }


    public AsyncWaitDialog()
    {
        InitializeComponent();
        _worker.DoWork += HandleDoWorkEvent;
        _worker.RunWorkerCompleted += HandleWorkerCompleted;
    }


    public void ShowDialogWhile(Action work)
    {
        _work = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();
    }

    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        _workWithReturn = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();

        return (TResult)Result;
    }


    private void HandleDoWorkEvent(object sender, EventArgs e)
    {
        try
        {
            if (_work != null)
            {
                _work();
            }
            if (_workWithReturn != null)
            {
                Result = _workWithReturn();
            }

        }
        catch (Exception)
        {
            this.Close();
            throw;
        }
    }

    private void HandleWorkerCompleted(object sender, EventArgs e)
    {
        this.Close();
    }

}
4

3 回答 3

2

您在编译时收到的错误与 Compact 框架无关,而是泛型的错误使用。正如其他人所说,除非您在类本身上声明它,否则 TResult 类型超出了您的类的范围。

如果我看一下您要实现的目标,我会说您可以通过将所有类型都保留在方法的本地来获得您想要的。进行如下更改:

public partial class AsyncWaitDialog : Form, IAsyncDialog
{
    ...
    //Func<TResult> _workWithReturn; REMOVE THIS LINE
    ...

    //Change your function to be this:
    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        var result = default(TResult);
        _work = () =>
        {
            result = work();
        };
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();

        return result;
    }
}

您的“工作”现在由调用您的函数的匿名委托执行,并且函数的返回保存在 ShowDialogWhile 函数的范围内。好又简单的把戏。

只是为了在那里进行重构,您可以使用现有方法来处理工作人员和对话逻辑:

    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        var result = default(TResult);
        ShowDialogWhile(() =>
        {
            result = work();
        });
        return result;
    }
于 2011-06-17T06:50:36.213 回答
1

您有一个带有 TResult 的通用方法,但您也有一个使用该类型的字段。如果您在运行时需要该类型的字段,请将泛型定义从方法移至类。

public partial class AsyncWaitDialog : Form, IAsyncDialog
{
    ...
    Func<TResult> _workWithReturn; //TRESULT IS NOT IN SCOPE
    ...

    public TResult ShowDialogWhile<TResult>(Func<TResult> work)
    {
        //TResult **IS** in scope here
        _workWithReturn = work;
        _worker.RunWorkerAsync();
        this.CenterForm();
        this.ShowDialog();

        return (TResult)Result;
    }


// possible solution, move the generic definition of TResult to the class definition

public partial class AsyncWaitDialog<TResult> : Form, IAsyncDialog { ... }
于 2011-06-16T18:33:25.403 回答
1

您的问题是这TResult是在方法上定义的泛型ShowDialogWhile,但您已声明您_workWithReturn超出了该范围。一种解决方法是将其TResult作为类声明的一部分。

于 2011-06-16T18:33:40.533 回答