想象一下,你有一个属性和一个私有字段:
private MessageBoxResult doNotUseMe_Result;
public MessageBoxResult MyResult
{
get { return doNotUseMe_Result; }
set
{
doNotUseMe_Result = value;
}
}
MessageBoxResult是一个枚举,用于获取MessageBox(WPF)的结果。然而,在将MyResult
传递给方法时遇到问题,因为它会自动使用枚举的值类型,并且GC
会收集更改的结果,因为它现在是一个全新的变量在我的方法范围内(TaskBasedShow
)......
我目前的设置:
public delegate void OnResult(MessageBoxResult res);
private MessageBoxResult doNotUseMe_Result;
public MainWindow()
{
InitializeComponent();
OnRes += MessageBox_OnRes;
TaskBasedShow("My message", "My caption", MessageBoxButton.YesNo, MessageBoxImage.Question, MyResult);
}
public MessageBoxResult MyResult
{
get { return doNotUseMe_Result; }
set
{
doNotUseMe_Result = value;
OnRes?.Invoke(value);
}
}
public void TaskBasedShow(string message, string caption, MessageBoxButton buttons,
MessageBoxImage image, MessageBoxResult resultprop)
{
Task.Factory.StartNew(() => { resultprop = MessageBox.Show(message, caption, buttons, image); });
}
/// <summary>
/// Is getting triggered after the user pressed a button.
/// </summary>
/// <param name="res">The pressed button.</param>
private void MessageBox_OnRes(MessageBoxResult res)
{
MessageBox.Show(res.ToString());
}
public event OnResult OnRes;
我确实已阅读以下文件:
但似乎enum
没有提供Set(value)
方法。
设置枚举属性的变量(在mothod 中)时,setter不会被触发,因此也不会触发我的自定义事件。
设置属性时应该触发OnRes
因为我的setter被触发,因此我的订阅者是OnResult
事件。工作范例:
public MainWindow()
{
InitializeComponent();
OnRes += MessageBox_OnRes;
MyResult = MessageBoxResult.Cancel;
}
它将打开另一个显示“取消”的消息框。
一种解决方案是使用TaskBasedShow
内的属性:
Task.Factory.StartNew(() => { MyResult = MessageBox.Show(message, caption, buttons, image); });
因为它现在使用引用类型而不是传递的值类型。
答案 0 :(得分:3)
您应该使用回调来获取结果值
public async void TaskBasedShow(
string message,
string caption,
MessageBoxButton buttons,
MessageBoxImage image,
Action<MessageBoxResult> resultCallback)
{
var result = await Task.Run(() => MessageBox.Show(message, caption, buttons, image ) );
resultCallback( result );
}
并将其称为
TaskBasedShow(
"My message",
"My caption",
MessageBoxButton.YesNo,
MessageBoxImage.Question,
r => MyResult = r );