我正在尝试在后台工作进程上做一些工作,当工作完成后,我想显示一个模态对话框。我有一个很好的代码工作代码,但希望能够传入一个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();
}
}
答案 0 :(得分:2)
编译时收到的错误与Compact框架无关,而是与Generics的错误使用有关。正如其他人所说,除非你在类中声明它,否则类型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函数的范围内。好的,简单的技巧。
只是在那里抛出一个重构,你可以使用现有的方法来处理worker和dialog逻辑:
public TResult ShowDialogWhile<TResult>(Func<TResult> work)
{
var result = default(TResult);
ShowDialogWhile(() =>
{
result = work();
});
return result;
}
答案 1 :(得分: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 { ... }
答案 2 :(得分:1)
您的问题是TResult
是ShowDialogWhile
方法定义的通用,但您已将_workWithReturn
声明为该范围。一种解决方法是将TResult
作为类声明的一部分。