模块摘要
通用有限状态机行为。
描述
用于实现有限状态机的行为模块。使用该模块实现的通用有限状态机进程(gen_fsm)将具有一组标准的接口函数,并包括用于跟踪和错误报告的功能。它也适用于OTP监督树。有关更多信息,请参阅OTP设计原则。
gen_fsm假定所有特定部分都位于回调模块中,导出预定义的函数集。行为函数和回调函数之间的关系可以说明如下:
gen_fsm module Callback module
-------------- ---------------
gen_fsm:start_link -----> Module:init/1
gen_fsm:send_event -----> Module:StateName/2
gen_fsm:send_all_state_event -----> Module:handle_event/3
gen_fsm:sync_send_event -----> Module:StateName/3
gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
- -----> Module:handle_info/3
- -----> Module:terminate/3
- -----> Module:code_change/4
如果回调函数失败或返回错误值,gen_fsm将终止。
gen_fsm处理系统消息,如sys(3)中所述。该SYS模块可用于调试gen_fsm。
请注意,gen_fsm不会自动捕获退出信号,必须在回调模块中明确启动。
除非另有说明,否则如果指定的gen_fsm不存在或者给出了错误的参数,则此模块中的所有函数都将失败。
如果回调函数指定'hibernate'而不是超时值,gen_fsm进程可以进入休眠状态(参见erlang(3))。如果预计服务器长时间处于空闲状态,这可能很有用。但是,应谨慎使用此功能,因为休眠意味着至少有两个垃圾收集(在休眠时和唤醒后不久),对于忙的状态机器并不想在每一次调用之间处理垃圾回收。
导出
start_link(Module, Args, Options) -> Result
start_link(FsmName, Module, Args, Options) -> Result
Types:
FsmName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Module = atom()
Args = term()
Options = [Option]
Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}
Dbgs = [Dbg]
Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
SOpts = [SOpt]
SOpt - 见erlang:spawn_opt/2,3,4,5
Result = {ok,Pid} | ignore | {error,Error}
Pid = pid()
Error = {already_started,Pid} | term()
创建gen_fsm进程作为监督树的一部分。该功能应由监督树直接或间接调用。除其他外,它将确保gen_fsm链接到监督树。
gen_fsm进程调用Module:init/1进行初始化。为确保同步启动过程,在Module:init/1返回之前,start_link/3,4不会返回。
如果FsmName = {local,Name},则gen_fsm使用register/2在本地注册为Name。如果FsmName = {global,GlobalName},则gen_fsm使用global:register_name/2全局注册为GlobalName。如果EventMgrName={via,Module,ViaName},则事件管理器注册用Module表示的注册表。所述模块的回调应该导出的函数register_name/2,unregister_name/1,whereis_name/1和send/2,其行为应与global中的相应函数相同。因此,{via,global,GlobalName}是有效的引用。
如果未提供名称,则不会注册gen_fsm。
Module是回调模块的名称。
Args是一个任意项,它作为参数传递给Module:init/1。
如果选项{timeout,Time}存在,则允许gen_fsm花费Time毫秒初始化,或者它将被终止,启动函数将返回 {error,timeout}。
如果存在选项{debug,Dbgs},则将为Dbgs中的每个项调用相应的sys函数。见sys(3)。
如果选项{spawn_opt,SOpts}存在,则SOpts将作为选项列表传递给spawn_opt BIF,后者用于生成gen_fsm进程。见erlang(3)。
注意
目前不允许使用spawn选项monitor,但会导致函数失败,原因为badarg。
如果gen_fsm成功创建并初始化,则函数返回{ok,Pid},其中Pid是gen_fsm的pid。如果已存在具有指定FsmName的进程,则该函数返回 {error,{already_started,Pid}},其中Pid是该进程的pid。
如果Module:init/1因Reason而失败,则函数返回{error,Reason}。如果Module:init/1返回{stop,Reason}或ignore,则进程终止,函数分别返回{error,Reason}或ignore。
start(Module, Args, Options) -> Result
start(FsmName, Module, Args, Options) -> Result
Types:
FsmName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Module = atom()
Args = term()
Options = [Option]
Option = {debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts}
Dbgs = [Dbg]
Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
SOpts = [term()]
Result = {ok,Pid} | ignore | {error,Error}
Pid = pid()
Error = {already_started,Pid} | term()
创建一个独立的gen_fsm进程,即gen_fsm,它不是监督树的一部分,因此没有监督者。
有关参数和返回值的说明,请参见start_link/3,4。
send_event(FsmRef, Event) -> ok
Types:
FsmRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Event = term()
将事件异步发送到gen_fsm FsmRef并立即返回ok。gen_fsm将调用Module:StateName/2来处理事件,其中StateName是gen_fsm的当前状态的名称。
FsmRef可以是:
pid,
Name,如果gen_fsm在本地注册,
{Name,Node},如果gen_fsm在另一个节点本地注册,或者
{global,GlobalName},如果gen_fsm是全局注册的,
{via,Module,ViaName},如果事件管理器是通过可选进程注册表注册的,
Event是一个任意项,作为Module:StateName/2的参数之一传递。
send_all_state_event(FsmRef, Event) -> ok
Types:
FsmRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Event = term()
将事件异步发送到gen_fsm FsmRef并立即返回ok。gen_fsm将调用Module:handle_event/3来处理事件。
有关参数的说明,请参阅send_event/2。
send_event和send_all_state_event之间的区别在于使用哪个回调函数来处理事件。在每个状态下发送事件以相同方式被处理,此函数很有用,因为在每个状态名称函数中只需要一个handle_event子句来处理事件而不是每个状态名函数一个子句。
sync_send_event(FsmRef, Event) -> Reply
sync_send_event(FsmRef, Event, Timeout) -> Reply
Types:
FsmRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Event = term()
Timeout = int()>0 | infinity
Reply = term()
将事件发送到gen_fsm FsmRef并等待,直到回复到达或发生超时。gen_fsm将调用Module:StateName/3来处理事件,其中 StateName是gen_fsm的当前状态的名称。
有关FsmRef和Event 的说明,请参阅send_event/2。
Timeout是一个大于零的整数,它指定等待回复的毫秒数,或无限期等待的原子infinity。默认值为5000.如果在指定时间内未收到回复,则函数调用失败。
返回值Reply在Module:StateName/3的返回值中定义。
在OTP R12B/Erlang 5.6中删除了在连接到客户端时,如果服务器在调用期间挂了,有时会消耗服务器退出消息的古老行为。
sync_send_all_state_event(FsmRef, Event) -> Reply
sync_send_all_state_event(FsmRef, Event, Timeout) -> Reply
Types:
FsmRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Event = term()
Timeout = int()>0 | infinity
Reply = term()
将事件发送到gen_fsm FsmRef并等待,直到回复到达或发生超时。gen_fsm将调用Module:handle_sync_event/4来处理事件。
有关FsmRef和Event的说明,请参阅send_event/2。有关Timeout和Reply的说明,请参阅sync_send_event/3。
见send_all_state_event/2,讨论sync_send_event和sync_send_all_state_event的区别。
reply(Caller, Reply) -> true
Types:
Caller - 见下面
Reply = term()
当无法在Module:State/3或Module:handle_sync_event/4的返回值中定义回复时,gen_fsm可以使用此函数向客户端进程显式发送回复,当调用sync_send_event/2,3或sync_send_all_state_event/2,3。
Caller必须是提供给回调函数的From参数。Reply是一个任意项,它将作为sync_send_event/2,3或sync_send_all_state_event/2,3的返回值返回给客户端。
send_event_after(Time, Event) -> Ref
Types:
Time = integer()
Event = term()
Ref = reference()
在gen_fsm内部发送延迟事件,在time ms后调用此函数。使用cancel_timer/1可用于取消延迟发送的引用,立即返回。
gen_fsm将调用Module:StateName/2来处理事件,其中StateName是传递延迟事件时gen_fsm的当前状态的名称。
Event是一个任意项,作为Module:StateName/2的参数之一传递。
start_timer(Time, Msg) -> Ref
Types:
Time = integer()
Msg = term()
Ref = reference()
在gen_fsm内部发送超时事件,在Time ms后调用此函数。立即返回可用于使用cancel_timer/1取消计时器的引用。
gen_fsm将调用Module:StateName/2来处理事件,其中StateName是传递超时消息时gen_fsm的当前状态的名称。
Msg是一个任意的术语,它在超时消息{timeout,Ref,Msg}中传递,作为Module:StateName/2的参数之一。
cancel_timer(Ref) -> RemainingTime | false
Types:
Ref = reference()
RemainingTime = integer()
取消gen_fsm中Ref引用的内部计时器。
Ref是从send_event_after/2 或 start_timer/2返回的引用。
如果计时器已经超时,但事件尚未发送,则会被取消,就好像它没有超时一样,因此从此函数返回后将没有错误的计时器事件。
如果Ref引用活动计时器,则返回以毫秒为单位的剩余时间,直到计时器到期为止,否则返回false。
enter_loop(Module, Options, StateName, StateData)
enter_loop(Module, Options, StateName, StateData, FsmName)
enter_loop(Module, Options, StateName, StateData, Timeout)
enter_loop(Module, Options, StateName, StateData, FsmName, Timeout)
Types:
Module = atom()
Options = [Option]
Option = {debug,Dbgs}
Dbgs = [Dbg]
Dbg = trace | log | statistics | {log_to_file,FileName} | {install,{Func,FuncState}}
StateName = atom()
StateData = term()
FsmName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Timeout = int() | infinity
将现有进程转换为gen_fsm。不返回,而是调用进程将进入gen_fsm接收receive循环并成为gen_fsm进程。该进程必须使用proc_lib中的启动函数被启动,参看proc_lib(3)。用户对进程初始化负责,包括注册名字。
当需要比gen_fsm行为提供的更复杂的初始化过程时,此函数很有用。
Module,Options和FsmName与调用start[_link]/3,4时的含义相同。但是,如果指定了FsmName,则必须在调用此函数之前相应地注册该进程。
StateName,StateData和Timeout与Module:init/1的返回值具有相同的含义 。此外,回调模块Module不需要导出init/1功能。
失败:如果调用进程未由proc_lib启动函数启动,或者未根据FsmName注册。
回调函数
应从gen_fsm回调模块导出以下函数。
在描述中,表达式state name用于表示状态机的状态。state data用于表示实现状态机的Erlang进程的内部状态。
导出
Module:init(InitArgs) -> {ok,State} | {ok,State,hibernate} | {error,Reason}
Types:
InitArgs = Args | {Args,Term}
Args = Term = term()
State = term()
Reason = term()
每当将新事件处理程序添加到事件管理器时,都会调用此函数来初始化事件处理程序。
如果添加了事件处理程序,由于调用gen_event:add_handler/3或gen_event:add_sup_handler/3,则InitArgs是这些函数的Args参数。
如果事件处理程序由于调用gen_event:swap_handler/3或gen_event:swap_sup_handler/3而替换另一个事件处理程序,或者由于来自其他一个回调函数的交换返回元组,则InitArgs是一个元组{Args,Term} 其中Args是函数call/return元组中提供的参数,Term是终止旧事件处理程序的结果,请参阅gen_event:swap_handler/3。
如果成功,该函数应返回{ok,State}或{ok,State,hibernate},其中State是事件处理程序的初始内部状态。
如果返回{ok,State,hibernate},则事件管理器将进入休眠状态(通过调用proc_lib:hibernate/3),等待下一个事件发生。
Module:StateName(Event, StateData) -> Result
Types:
Event = timeout | term()
StateData = term()
Result = {next_state,NextStateName,NewStateData}
| {next_state,NextStateName,NewStateData,Timeout}
| {next_state,NextStateName,NewStateData,hibernate}
| {stop,Reason,NewStateData}
NextStateName = atom()
NewStateData = term()
Timeout = int()>0 | infinity
Reason = term()
每个可能的状态名称应该有一个此函数的实例。每当gen_fsm接收到使用gen_fsm:send_event/2发送的事件时,将调用与当前状态名称StateName同名的此函数的实例来处理该事件。 如果发生超时,也会调用它。
事件是原子timeout,如果发生超时,Event提供参数给send_event/2。
StateData是gen_fsm的状态数据。
如果函数返回{next_state,NextStateName,NewStateData},{next_state,NextStateName,NewStateData,Timeout}或{next_state,NextStateName,NewStateData,hibernate},gen_fsm将继续执行,当前状态名称设置为NextStateName并且可能更新状态数据NewStateData。 有关Timeout和hibernate的说明,请参阅Module:init/1。
如果函数返回{stop,Reason,NewStateData},gen_fsm将调用Module:terminate(Reason,NewStateData)并终止。
Module:handle_event(Event, StateName, StateData) -> Result
Types:
Event = term()
StateName = atom()
StateData = term()
Result = {next_state,NextStateName,NewStateData}
| {next_state,NextStateName,NewStateData,Timeout}
| {next_state,NextStateName,NewStateData,hibernate}
| {stop,Reason,NewStateData}
NextStateName = atom()
NewStateData = term()
Timeout = int()>0 | infinity
Reason = term()
每当gen_fsm接收到使用gen_fsm:send_all_state_event/2发送的事件时,就会调用此函数来处理该事件。
StateName是gen_fsm的当前状态名称。
有关其他参数和可能的返回值的说明,请参阅Module:StateName/2。
Module:StateName(Event, From, StateData) -> Result
Types:
Event = term()
From = {pid(),Tag}
StateData = term()
Result = {reply,Reply,NextStateName,NewStateData}
| {reply,Reply,NextStateName,NewStateData,Timeout}
| {reply,Reply,NextStateName,NewStateData,hibernate}
| {next_state,NextStateName,NewStateData}
| {next_state,NextStateName,NewStateData,Timeout}
| {next_state,NextStateName,NewStateData,hibernate}
| {stop,Reason,Reply,NewStateData} | {stop,Reason,NewStateData}
Reply = term()
NextStateName = atom()
NewStateData = term()
Timeout = int()>0 | infinity
Reason = normal | term()
每个可能的状态名称应该有一个此函数的实例。每当gen_fsm接收到使用gen_fsm:sync_send_event/2,3发送的事件时,将调用与当前状态名称StateName同名的此函数的实例来处理该事件。
Event是提供给sync_send_event的Event参数。
From是一个元组{Pid,Tag},其中Pid是名为sync_send_event/2,3进程的pid,Tag是唯一标记。
StateData是gen_fsm的状态数据。
如果函数返回{reply,Reply,NextStateName,NewStateData},{reply,Reply,NextStateName,NewStateData,Timeout}或{reply,Reply,NextStateName,NewStateData,hibernate},则Reply将给回到From作为sync_send_event/2,3的返回值。然后gen_fsm继续执行,当前状态名称设置为NextStateName,并且可能更新状态数据NewStateData。有关Timeout和hibernate的说明,请参阅Module:init/1。
如果函数返回{next_state,NextStateName,NewStateData},{next_state,NextStateName,NewStateData,Timeout}或{next_state,NextStateName,NewStateData,hibernate},gen_fsm将继续使用NewStateData在NextStateName中执行。必须使用gen_fsm:reply/2明确给出对From的任何回复。
如果函数返回{stop,Reason,Reply,NewStateData},则回复将返回From。如果函数返回{stop,Reason,NewStateData},则必须使用gen_fsm:reply/2显式给出对From的任何回复。然后gen_fsm将调用Module:terminate(Reason,NewStateData)并终止。
Module:handle_sync_event(Event, From, StateName, StateData) -> Result
Types:
Event = term()
From = {pid(),Tag}
StateName = atom()
StateData = term()
Result = {reply,Reply,NextStateName,NewStateData}
| {reply,Reply,NextStateName,NewStateData,Timeout}
| {reply,Reply,NextStateName,NewStateData,hibernate}
| {next_state,NextStateName,NewStateData}
| {next_state,NextStateName,NewStateData,Timeout}
| {next_state,NextStateName,NewStateData,hibernate}
| {stop,Reason,Reply,NewStateData} | {stop,Reason,NewStateData}
Reply = term()
NextStateName = atom()
NewStateData = term()
Timeout = int()>0 | infinity
Reason = term()
每当gen_fsm接收到使用gen_fsm:sync_send_all_state_event/2,3发送的事件时,将调用此函数来处理该事件。
StateName是gen_fsm的当前状态名称。
有关其他参数和可能的返回值的说明,请参阅Module:StateName/3。
Module:handle_info(Info, StateName, StateData) -> Result
Types:
Info = term()
StateName = atom()
StateData = term()
Result = {next_state,NextStateName,NewStateData}
| {next_state,NextStateName,NewStateData,Timeout}
| {next_state,NextStateName,NewStateData,hibernate}
| {stop,Reason,NewStateData}
NextStateName = atom()
NewStateData = term()
Timeout = int()>0 | infinity
Reason = normal | term()
当gen_fsm接收到除同步或异步事件(或系统消息)之外的任何其他消息时,将调用此函数。
Info是收到的消息。
有关其他参数和可能的返回值的说明,请参阅Module:StateName/2。
Module:terminate(Reason, StateName, StateData)
Types:
Reason = normal | shutdown | {shutdown,term()} | term()
StateName = atom()
StateData = term()
当gen_fsm即将终止时,该函数被gen_fsm调用。它应该与Module:init/1相反,并进行任何必要的清理。返回时,gen_fsm以Reason结束。返回值被忽略。
Reason是表示停止原因的术语,StateName是当前状态名称,StateData是gen_fsm的状态数据。
Reason取决于gen_fsm为何终止。如果是因为另一个回调函数返回了一个停止元组{stop,..},则Reason将具有该元组中指定的值。如果是由于失败,则Reason是错误原因。
如果gen_fsm是监督树的一部分并且由其主管命令终止,则如果满足以下条件,则将使用Reason = shutdown调用此函数:
gen_fsm已被设置为捕获退出信号,并且监督者的子规范中定义的关闭策略是整数超时值,而不是brutal_kill。
即使gen_fsm不是监督树的一部分,如果它从其父级接收到“EXIT”消息,也将调用该函数。Reason与“EXIT”消息中的原因相同。
否则,gen_fsm将立即终止。
请注意,除了正常,关闭或{shutdown,Term}之外的任何其他原因,假定gen_fsm由于错误而终止,并且使用error_logger:format/2发出错误报告。
Module:code_change(OldVsn, StateName, StateData, Extra) -> {ok, NextStateName, NewStateData}
Types:
OldVsn = Vsn | {down, Vsn}
Vsn = term()
StateName = NextStateName = atom()
StateData = NewStateData = term()
Extra = term()
当gen_fsm在发布升级/降级期间更新其内部状态数据时,即在appup文件中给出Change= {advanced,Extra}的指令{update,Module,Change,...}时,将调用此函数。 见OTP设计原则。
在升级的情况下,OldVsn是Vsn,在降级的情况下,OldVsn是{down,Vsn}。 Vsn由旧版本的回调模块Module的vsn属性定义。 如果未定义此类属性,则版本是BEAM文件的校验和。
StateName是当前状态名称,StateData是gen_fsm的内部状态数据。
Extra从更新指令的{advanced,Extra}部分按原样传递。
该函数应返回新的当前状态名称和更新的内部数据。
Module:format_status(Opt, [PDict, StateData]) -> Status
Types:
Opt = normal | terminate
PDict = [{Key, Value}]
StateData = term()
Status = term()
请注意,该回调可选,所以回调模块不需要导出它,这个回调模块提供一个默认实现,该函数返回回调模块状态。
在以下情况下,gen_fsm进程会调用此函数:
调用sys:get_status/1,2之一以获取gen_fsm状态。对于这种情况,Opt设置为原子normal。
gen_fsm异常终止并记录错误。对于这种情况,选项设置为原子terminate。
此函数可用于自定义这些情况的gen_fsm状态的形式和外观。希望自定义sys:get_status/1,2返回值以及其状态如何在终止错误日志中出现的回调模块导出format_status/2的实例,该实例返回描述gen_fsm当前状态的术语。
PDict是gen_fsm的进程字典的当前值。
StateData是gen_fsm的内部状态数据。
该函数应返回Status,这是一个定制gen_fsm当前状态和状态详细信息的术语。状态可以采取的形式没有限制,但对于sys:get_status/1,2情况(当Opt是normal时),Status值的推荐形式为[{data,[{“StateData”,Term}]其中Term提供gen_fsm状态数据的相关详细信息。不需要遵循此建议,但这样做会使回调模块状态与sys:get_status/1,2返回值的其余部分保持一致。
此函数的一个用途是返回紧凑的替代状态数据表示,以避免在日志文件中打印大的状态术语。
- Erlang模块erl翻译
命令: erl 概述: Erlang模拟器 描述: erl程序启动一个Erlang运行时系统.准确的信息是依赖于系统的(举例,erl是否是脚本或程序,其它程序调用). ...
- Erlang模块file翻译
模块摘要 文件接口模块 描述 模块file提供了文件系统的接口. 在具有线程支持的操作系统上,可以让文件操作以其自己的线程执行,从而允许其他Erlang进程与文件操作并行地 ...
- Erlang模块ets翻译
概要: 内置的存储 描述: 这个模块是Erlang内置存储BIFs的接口.这些提供了在Erlang运行时系统中存储大量数据的能力,并且能够对数据进行持续的访问时间.(在ordered_set的情况下, ...
- Erlang模块supervisor翻译
概要: 通用监督者行为 描述: 一个实现监督者的行为模块,一个监督被称为子进程的其它进程的进程.一个子进程可以是另一个监督者或工作者进程.工作者进程通常的实现使用gen_event,gen_fsm ...
- Erlang模块gen_server翻译
gen_server 概要: 通用服务器行为描述: 行为模块实现服务器的客户端-服务器关系.一个通用的服务器进程使用这个模块将实现一组标准的接口功能,包括跟踪和错误报告功能.它也符合OTP进程监控树. ...
- Erlang模块gen_tcp翻译
概述 TCP/IP套接字接口 描述 gen_tcp模块提供了使用TCP / IP协议与套接字进行通信的功能. 以下代码片段提供了一个客户端连接到端口5678的服务器的简单示例,传输一个二进制文件并关闭 ...
- Erlang模块inet翻译
模块 inet 模块概述 访问TCP / IP协议. 描述 此模块提供对TCP/IP协议的访问. 另请参阅<ERTS用户指南:Inet配置>,以获取有关如何配置用于IP通信的Erlang运 ...
- [Erlang25]Erlang in anger 翻译
Erlang in anger Erlang in anger 是写Learn some Erlang的帅小伙(照片真是帅死啦)写的,一共87页,可以随意下载(英文原版):http://www ...
- ns3 Tutorial 中的日志模块(翻译)
转载地址:http://blog.sina.com.cn/s/blog_8ecca79b0101d7fe.html 1 日志模块的使用 在运行 first.cc 脚本时,我们已经简单 ...
随机推荐
- quick-cocos2dx在eclipse下的lua调试
文中大部分内容来自http://cn.quick-x.com/?p=253,绿色标记部分为修改部分. 配置编译环境的基本步骤: 安装 Visual Studio 2012 安装 Java SDK 安装 ...
- Ubuntu 18.04 LTS版本 GoldenDict安装与配置
为何安装? GoldenDict是一款Linux下很好用的词典软件,其具有的关于词典的裁剪功能使得用户能够方便地对各种词典进行添加或删除,其具有的屏幕取词功能能够帮助用户方便地进行翻译,其具有的网络源 ...
- 页面性能监控之performance
页面性能监测之performance author: @TiffanysBear 最近,需要对业务上的一些性能做一些优化,比如降低首屏时间.减少核心按钮可操作时间等的一些操作:在这之前,需要建立的就是 ...
- c# NPOI 导出23万条记录耗时12秒
先上测试代码: string connectionString = "Server=localhost;Initial Catalog=******;User ID=sa;Password= ...
- MBR和EFI启动过程
MBR启动过程 BIOS-->MBR(主引导记录)-->DPT(硬盘分区表)-->DBR(分区引导扇区)-->BootMgr-->BCD-->Winload.exe ...
- Vue-Router中History模式
目录 history路由 官方示例 Express中间件 客户端兜底404 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在 ...
- MyBatis的flushCache和useCache的使用注意
之前在利用MyBatis做开发的时候,遇到了一个问题,使用select配置的时候发现前后两次的结果是一样的,并且使用statementType="CALLABLE"配置,然后在配置 ...
- DBUtils框架的使用(下)
刚才讲了使用QueryRunner插入.修改.更新数据,现在来学习一下使用QueryRunner进行数据库表查询. 通过QueryRunner类的query()方法即可完成数据库表的查询操作,但是在查 ...
- .net测试篇之Moq行为配置
系列目录 我们前面说过.Moq在创建模拟对象的时候,简单对象赋值默认值,引用对象赋值为null,但是有些时候接口里面还包含另一个接口对象,我们知道Moq是可以模拟一个接口对象的,我们可以通过配置让Mo ...
- 在Keras中使用VGG进行物体识别(直接使用)
https://blog.csdn.net/baimafujinji/article/details/80700263