我有一个ICommand需要将数据设置为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并使用logging属性修饰该方法,但我无法在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);
}
问题是看起来好像我仍然在后台线程上设置属性而不是主线程(Android中的IllegalStateException)。
在第一个示例中设置数据的最简洁方法是什么,同时仍将Action
包装在日志记录方法中?
我也成功为ICommand
创建基类,但是它A)更改了CanExecute
和Execute
的方法签名,而B)它(显然)也没有将其功能扩展到Commands
以外。
我正在寻找一种干净的方法来记录方法(BeforeExecute,AfterExecute,OnError),无论他们做什么。
顺便说一下,理想的日志记录机制是使用拦截器,但是我在C#chops中实施它并不够强大。
[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.
}
答案 0 :(得分:0)
如果您(在下面警告)访问代码中的Activity对象,那么您可以这样做;
Activity.RunOnUiThread(() => {
//Execute my code on UIThread here
});
但它是 if ,因为我注意到您正在使用PCL,或者使用过PCL,所以我怀疑共享库不会知道任何事情关于活动(除非你也通过了)。在很大程度上取决于您的应用程序结构以及此代码的位置,但在主要的Xamarin.Android项目中,您的视图应该可以正常工作