XILINXFPGA数字信号处理权威指南从HDL到模型和C的描述.pdf
XILINX FPGA数字信号处理权威指南 从HDL到模型和C的描述pdf⾼清版本
⽂件: (访问密码:551685)
以下内容⽆关:
-------------------------------------------分割线---------------------------------------------
前⾔#
 曾经我以学习的⽬的写了关于在.NET Core3.1使⽤Prism的系列⽂章.NET Core 3 WPF MVVM框架 Prism系列⽂章索引,也谢谢⼤家的⽀持,事实上当初的版本则是Prism7.2.0.1442(7.2)版本,⽽现在也发布了.NET5和最新的Prism8.0.0.1909(8.0)版本,因此同样的我想将之前的Prism Demo项⽬可以升级到最新,写这篇⽂章的⽬的是⾃⼰也能学习⼀番,⽽更多的是回答那些在我Prism系列⽂章下⾯留下的我认为可以拿来⼀讲⼀些问题,⽽有些问题我则是⽔平有限回答不了(真的不是不想回答)
 然后我拿之前的Prism Demo项⽬,WPF从.NET Core3.1升级到.NET 5其实⾮常简单,⽆脑修改项⽬的TargetFramework为net5.0-windows就⾏了,但是当Prism7.2升级到Prism8.0,我发现build的时候报了很多错误,那么让我们来看看究竟Prism8.0更新了些啥
⼀ .Prism8.0更新了什么?#
我们先来看下关于Prism7.2和Prism8.0的程序集引⽤情况,可推敲出⼀些不同:
这⾥可能不会讲述所有关于Prism8.0更新的全部细节,只是我认为可能主要的⼀些功能,我们可以看到Prism8.0相⽐Prism7.2,在Prism.WPF中去除了System.Windows.Interactivity和CommonServiceLocator程序集,引⼊了Microsoft.Xaml.Behaviors.Wpf,实际上Prism8.0做了以下整合:
⽤Microsoft.Xaml.Behaviors.Wpf替换System.Windows.Interactivity
CommonServiceLocator整合⼊Prism.Core之中
因为你从旧版本更新到Prism8.0可能会发⽣报错,⽽我的⽬的则是⼀篇更新指南,关于Prism8.0更新的全部细节,可以看官⽅在github的Prism8.0的ReleaseNote,这⾥还推荐Dior⼤佬的有关Prism8.0的⽂章:[Windows] Prism 8.0 ⼊门(上):Prism.Core和[Windows] Prism 8.0 ⼊门(下):Prism.Wpf 和 Prism.Unity
1.ContainerLocator.Current.Resolve函数去除:#
Copy
ContainerLocator.Current.Resolve
//替换为
ServiceLocator.Current.GetInstance
 这可能是你遇到的第⼀个升级报错,因为ContainerLocator.Current.Resolve这个api本来是在Prism.WPF下的CommonServiceLocator程序集下⾯的,8.0时候被砍了,在Prism.Core加上ServiceLocator.Current.GetInstance⽤于替换,切掉了CommonServiceLocator程序集,我觉得⾮常合理,因为该功能本⾝就应该是IOC⾥⾯的公共功能
3.去除 Bootstrapper :#
Copy
public partial class App : Bootstrapper
//替换成
public partial class App : PrismApplication //(推荐)其他平台也⽀持
/
/or
public partial class App : PrismBootstrapper //WPF独有
 这可能是你遇到的第三个升级报错,我们在App.cs中都会集成⼀个底层类⽤于注册或者配置,其实在Prism7.2的时候Bootstrapper 已经被标记为弃⽤状态,⽽在Prism8.0更是直接删除,推荐继承PrismApplication(各平台都⽀持),当然也可以选择PrismBootstrapper (WPF独有)
4.IOC添加新注册功能:#
 其实IOC这部分功能我不打算细讲,因为其实不属于Prism的特性功能,因为Prism默认⽀持两个IOC扩展,也就是Unity和DryIoc的,⽽新添加的功能也是对应通过两个IOC⽀持实现的,直接看代码⽰例:
Copy
public interface ITestService { }
public interface ITest2Service { }
public class TestService : ITestService, ITest2Service { }
private static ITestService TestDelegate() =>new TestService();
//添加⽀持注册多服务对应单实现类的功能
var services = new[] { typeof(ITestService), typeof(ITest2Service) };
IContainerRegistry.RegisterManySingleton(services);//注册成单例模式
IContainerRegistry.RegisterMany(services);//注册成瞬时模式
//添加⽀持注册服务为scope(范围模式)
IContainerRegistry.RegisterScoped(typeof(TestService))//单服务
IContainerRegistry.RegisterScoped(typeof(TestService), typeof(TestService))//单服务
IContainerRegistry.RegisterScoped();//单服务泛型版本
IContainerRegistry.RegisterScoped(typeof(ITestService), typeof(TestService))//单服务单实现
//添加⽀持通过委托⽅法注册服务
IContainerRegistry.Register(typeof(ITestService), TestDelegate)//注册为瞬时模式
IContainerRegistry.RegisterSingleton(typeof(ITestService), TestDelegate)//注册为单例模式
IContainerRegistry.RegisterScoped(typeof(ITestService), TestDelegate)//注册为范围模式
5.添加了有关在void⽅法中异步等待Task的扩展⽅法:#
 你乍⼀看好像没什么卵⽤,但是⾥⾯还是有说法的,我们来看⼀个例⼦,WPF界⾯MVVM异步读取耗时数据加载界⾯,这⾥是xaml的简化代码::
ViewModel简化代码:
Copy
private ObservableCollection _allMedicines=new ObservableCollection();
public ObservableCollection AllMedicines
{
get { return _allMedicines; }
set { _allMedicines = value; }
}
private DelegateCommand _loadCommand;
public DelegateCommand LoadCommand =>
_loadCommand ?? (_loadCommand = new DelegateCommand(ExecuteLoadCommand));
async void ExecuteLoadCommand()
{
await ALongTask();
this.AllMedicines.AddRange(_medicineSerivce.GetAllMedicines());
}
private async Task ALongTask()
{
await Task.Delay(3000);//模拟耗时操作
Debug.WriteLine(“耗时操作完成”);
}
这是正常我们会实现的⽅式,同样的也确实不会出现跨线程问题(在⾮UI线程操作ObservableCollection集合会出现),关于async await在WPF不会出现跨线程问题,可以参考我的另外⼀篇⽂章异步函数async await在wpf都做了什么?,也同样的在执⾏耗时操作时候不会阻塞UI 主线程,如果在最上层不⽤async void能否实现同样的效果,这就是TaskExtension的意义了,下⾯只例举⾮泛型版本TaskExtension的api,,实际还有泛型版本的TaskExtension,我们拿最多参数的重载⽅法来说明:
public static class TaskExtensions
{
public static async void Await(this Task task, Action completedCallback, Action errorCallback, bool configureAwait)
{
try
{
await task.ConfigureAwait(configureAwait);
completedCallback?.Invoke();
}
catch (Exception obj)
{
errorCallback?.Invoke(obj);
}
}
}
1pletedCallback:当前Task的回调函数,指Task执⾏的后续操作
我们可以把ExecuteLoadCommand⽅法修改下:
Copy
void ExecuteLoadCommand()
{
//TaskExtension for async void Command
ALongTask().Await( completedCallback:() =>
{
this.AllMedicines.AddRange(_medicineSerivce.GetAllMedicines());
}, errorCallback:null,configureAwait:true);
}
该⽅式执⾏效果和之前⼀样,⽽且不⽤在void⽅法加上async 和⽅法内部await就能实现异步等待操作,⽽这只是推荐在Command的Excuted Method使⽤,这也是官⽅推荐的,因为⼀般Excuted Method返回值只会是void
⼆.回答⼀些问题#
如何在Prism使⽤AOP?#
 其实AOP并不是属于prism特有的功能,但是由于prism⽀持扩展IOC容器:Unity和DryIoc,只要其IOC容器本⾝⽀持,那就可以,由于默认Prism是以Unity为默认IOC容器,所以以Unity为例⼦:
NuGet引⽤Unity AOP库:Unity.Interception(最新是5.11.1)
在App.cs添加扩展AOP,代码如下:
Copy
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
var container = PrismIocExtensions.GetContainer(containerRegistry);
container.AddNewExtension()//add Extension Aop
//注册服务和添加显⽰拦截
.RegisterType<IMedicineSerivce, MedicineSerivce>(new Interceptor(), new InterceptionBehavior())
.RegisterType<IPatientService, PatientService>(new Interceptor(), new InterceptionBehavior())
.RegisterType<IUserService, UserService>(new Interceptor(), new InterceptionBehavior());
}
新建类LogHandler继承ICallHandler⽤于处理拦截逻辑和特性LogHandlerAttribute,模拟记录Log,:
public class LogHandler : ICallHandler
{
public int Order { get ; set ; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Debug.WriteLine("-------------Method Excute Befored-------------");
Debug.WriteLine($"Method Name:{input.MethodBase.Name}");
if (input.Arguments.Count>0)
{
Debug.WriteLine("Arguments:");
for (int i = 0; i < input.Arguments.Count; i++)
{
Debug.WriteLine($"parameterName:{input.Arguments.ParameterName(i)},parameterValue:{input.Arguments[i]}");          }
}
var methodReturn = getNext()(input, getNext);
Debug.WriteLine("-------------Method Excute After-------------");
if (methodReturn.Exception!=null)
{
Debug.WriteLine($"Exception:{methodReturn.Exception.Message} \n");
}
else
{
Debug.WriteLine($"Excuted Successed \n");
}
return methodReturn;
}
}
public class LogHandlerAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LogHandler() { Order = this.Order };
}
}
为那些需要拦截的接⼝标上Attribute
Copy
[LogHandler]
public interface IMedicineSerivce
{
List GetAllMedicines();
List GetRecipesByPatientId(int patientId);
}
[LogHandler]
public interface IPatientService
{
List GetAllPatients();
}
[LogHandler]
public interface IUserService
{
List GetAllUsers();
}
效果如下:
Copy
-------------Method Excute Befored-------------
Method Name:GetAllMedicines
-------------Method Excute After-------------
Excuted Successed
-------------Method Excute Befored-------------
Method Name:GetRecipesByPatientId
Arguments:
parameterName:patientId,parameterValue:1
-------------Method Excute After-------------
Excuted Successed
-------------Method Excute Befored-------------
Method Name:GetRecipesByPatientId
Arguments:
parameterName:patientId,parameterValue:2
-------------Method Excute After-------------
Excuted Successed
-------------Method Excute Befored-------------
Method Name:GetRecipesByPatientId
Arguments:
parameterName:patientId,parameterValue:3
-------------Method Excute After-------------
Excuted Successed
-------------Method Excute Befored-------------
Method Name:GetRecipesByPatientId
Arguments:
parameterName:patientId,parameterValue:4
-------------Method Excute After-------------
Excuted Successed
 当然这⾥篇幅有限,不可能讲述有关太多Unity AOP的细节,实际上Unity AOP功能⾮常强⼤,同样⽀持通过配置⽂件来配置AOP和⽀持对不同类型⽅法的拦截,需要了解更多细节在这⾥可推荐该博⽂C#中AOP_使⽤Unity实现AOP
typeof的用法是否所有事件和逻辑都在ViewModel处理?#
 WPF是个数据驱动型程序,当使⽤MVVM框架如Prism或者MVVMLight的时候,我们会在ViewModel处理业务数据逻辑,通过Binding⽅式驱动前台界⾯的显⽰,如果处理逻辑是View相关的,例如对控件的样式变化,⿏标移动控件等View逻辑相关的,这时候则推荐⽤依赖或者附加属性,或在View的Code-behind的cs⽂件中事件来处理有关View的逻辑,不要为了所谓的MVVM⽽把⼀切逻辑都放在ViewModel处理,实则更加不灵活,反⽽跟之前的MVC都放在C中处理没啥区别了

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。