我有一个ICommand需要将数据设置为UI线程上的属性。编组数据回到UI线程从异步动作
public override async void Execute(object parameter)
{
var vm = (MyVm)parameter;
var data = await _myDataService.GetData();
vm.MyData = data; // must be set on UI Thread due to binding.
}
现在我想换我的电话在事件记录器(我本来想做AOP和装饰用日志记录属性的方法,但我无法弄清楚在PCL)。于是我开始像这样打包我的电话。
public override void Execute(object parameter)
{
EventLogger.LogEvent(this,
EventLogEntryType.Command,
EventLogErrorSeverity.Warning,
Errors.GetServiceAreaCommand_ErrorMessage,
async() =>
{
var vm = (MyVm)parameter;
var data = await _myDataService.GetData();
vm.MyData = data; // must be set on UI Thread due to binding.
});
}
这里是LogEvent方法。
public static void LogEvent(object sender,
EventLogEntryType entryType,
EventLogErrorSeverity eventLogErrorSeverity,
string friendlyErrorMessage,
Action action)
{
var name = sender.GetType().Name.SplitCamelCase();
var startEntry = new EventLogEntry(entryType);
LogEvent(string.Format("Start: {0}", name), startEntry);
try
{
action.Invoke();
}
catch (Exception ex)
{
var exEntry = new EventLogEntry(EventLogEntryType.Error, friendlyErrorMessage, false, ex)
{
ErrorSeverity = eventLogErrorSeverity
};
LogEvent(string.Format("Error: {0}", name), exEntry);
if (eventLogErrorSeverity == EventLogErrorSeverity.Critical)
{
throw;
}
}
var endEntry = new EventLogEntry(entryType);
LogEvent(string.Format("Finish: {0}", name), endEntry);
}
的问题是,它看起来好像我还是设置在后台线程而非主线程(IllegalStateException异常Android中)财产。
什么是最简洁的方式来设置数据,因为在第一个示例中正在完成,同时仍然在登录方法中包装Action
?
我也有过成功创建ICommand
一个基类,但A)改变了方法签名CanExecute
和Execute
,和B)还(显然)不会延伸它的能力超越Commands
。
我正在寻找一种干净的方式来记录方法(BeforeExecute,AfterExecute,OnError),无论他们做什么。另外,理想的日志记录机制应该是使用拦截器,但是我的C#排版实现它的能力还不够强。
[Log(EventLogEntryType.Command, EventLogErrorSeverity.Warning, "Some Friendly Message")]
public override async void Execute(object parameter)
{
var vm = (MyVm)parameter;
var data = await _myDataService.GetData();
vm.MyData = data; // must be set on UI Thread due to binding.
}
我实际上使用Xamarin.Forms,所以还有'Device.BeginInvokeOnMainThread(() => {});' –