gpt4 book ai didi

c# - WF4 中的状态机

转载 作者:行者123 更新时间:2023-11-30 22:35:00 24 4
gpt4 key购买 nike

首先是免责声明 - 我是 WF 的新手,我只玩 WF4 3 天 - 所以对于我可能有的任何良性或蹩脚的问题表示歉意...

我正在尝试在我的项目中实现 WF4 状态机。以下是一些背景信息:

  1. 我将 WinForm UI 作为主要应用程序,可以为网络堆栈生成不同的命令
  2. 我将接口(interface)层作为 DLL 从网络堆栈接收事件
  3. 状态机应该在与接口(interface)层平行的中间层某处实现软电话状态机。电话状态根据网络事件和用户操作而改变。有些用户操作只会导致网络命令,有些可能会直接影响状态机。
  4. 我的接口(interface)层实现了一个对象 Phone,所以我将这个对象作为状态机的宿主。我将主界面对象 WinSipItf 传递给电话对象,并执行以下操作(WinSipItf 对象位于另一个 namespace WinSipNetLib 中):

代码:

public void Initialize(WinSipNetLib.WinSipItf winSipItf, string hostname, string user, string password)
{
try
{
WinSipItf = winSipItf;
var Itf = WinSipItf;
var input = new Dictionary<string, object>
{
{"winSipItf", Itf}
};
this.WorkFlowHostApp = new WorkflowApplication(new Activity1(), input)
{
Idle = this.OnWorkflowIdle,
Completed = this.OnWorkflowCompleted
};

// Setup the Tracking to output in the debug window
WorkFlowHostApp.Extensions.Add(new Tracker());

this.WorkFlowHostApp.Extensions.Add(this);

this.workflowBusy.Reset();

Console.WriteLine("Starting Workflow");
this.WorkFlowHostApp.Run();
}
catch (Exception ex)
{
Console.Write(ex);
}
}

电话初始状态为 Initial,它具有目标状态 PhoneIdle 的自动/空触发器。 OnEntrace 到初始状态我需要使用网络堆栈执行几个电话注册 - 注册回调(同步操作)并注册网络堆栈管理器(异步)。所有这些功能都存在于我通过接口(interface)层中构造的 API 访问的较低级别的非托管代码中。成功注册后,我在界面层收到一个回调并触发一个事件。因此我的注册事件看起来像这样:

public sealed class Register : NativeActivity<Int32>
{
// Define an activity input argument of type string
[RequiredArgument]
public InArgument<WinSipNetLib.WinSipItf> winSipItf { get; set; }

#region Constants and Fields

private readonly Variable<NoPersistHandle> _noPersistHandle = new Variable<NoPersistHandle>();
internal const string BookmarkName = "WaitingForAccountStatusEvent";

/// <summary>
/// The transition callback.
/// </summary>
private BookmarkCallback registrationCallback;

#endregion

#region Properties

///// <summary>
///// Gets or sets PhoneTransition.
///// </summary>
//public PhoneTransition PhoneTransition { get; set; }

/// <summary>
/// Gets a value indicating whether CanInduceIdle.
/// </summary>
protected override bool CanInduceIdle
{
get
{
return true;
}
}

/// <summary>
/// Gets TransitionCallback.
/// </summary>
private BookmarkCallback RegistrationCallback
{
get
{
return this.registrationCallback ?? (this.registrationCallback = new BookmarkCallback(this.OnRegistrationCallback));
}
}

#endregion

#region Methods

/// <summary>
/// The cache metadata.
/// </summary>
/// <param name="metadata">
/// The metadata.
/// </param>
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
metadata.RequireExtension(typeof(Tracker));
metadata.RequireExtension(typeof(Phone));
metadata.RequireExtension(typeof(WaitForRegistrationExt));
// !!! and one more for GUI

// Provide a Func<T> to create the extension if it does not already exist
metadata.AddDefaultExtensionProvider(() => new WaitForRegistrationExt());

metadata.AddArgument(new RuntimeArgument("winSipItf", typeof(WinSipNetLib.WinSipItf), ArgumentDirection.In, true));
metadata.AddArgument(new RuntimeArgument("Result", typeof(int), ArgumentDirection.Out, false));

metadata.AddImplementationVariable(_noPersistHandle);
}

protected override void Execute(NativeActivityContext context)
{
// Enter a no persist zone to pin this activity to memory since we are setting up a delegate to receive a callback
var handle = _noPersistHandle.Get(context);
handle.Enter(context);

// Get Phone extension needed to call the functions in WinSipItf
Phone phone = (Phone)context.GetExtension<Phone>();

// Get (which may create) the extension
WaitForRegistrationExt regExt = context.GetExtension<WaitForRegistrationExt>();

// Add the callback
regExt.AddRegistrationCallback(winSipItf.Get(context));

bool bRet = phone.WinSipItf.RegisterDBusCallback("WinSipPhone");

// Obtain the runtime value of the Text input argument
if (bRet == false)
{
this.Result.Set(context, bRet.ToString());
return;
}

string hostname = "demo2.demo.com";
string username = "406";
string password = "123123";
string id = username + "@" + hostname;
String regUri = hostname;
if (phone.WinSipItf.DoSipRegister(id, regUri, username, password) == 0)
{
this.Result.Set(context, bRet.ToString());
return;
}

// Set a bookmark - the extension will resume when the Gizmo is fired
context.CreateBookmark(BookmarkName, RegistrationCallback);

//context.CreateBookmark(this.PhoneTransition.ToString(), this.RegistrationCallback);

//// Obtain the runtime value of the Text input argument
//string text = context.GetValue(this.Text);

//Result.Set(context, string.Format("The text is {0}", text));
}

/// <summary>
/// The on transition callback.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
/// <param name="bookmark">
/// The bookmark.
/// </param>
/// <param name="value">
/// The value.
/// </param>
/// <exception cref="InvalidOperationException">
/// </exception>
private void OnRegistrationCallback(NativeActivityContext context, Bookmark bookmark, object value)
{
if (value is WinSipItf.MSGDATA)
{

}
////if (value is StateTransitionResult)
//{
// this.Result.Set(context, value as StateTransitionResult);
//}
//else if (value != null)
//{
// // Resumed with something else
// throw new InvalidOperationException(
// "You must resume PhoneTransition bookmarks with a result of type StateTransitionResult");
//}

// Exit the no persist zone
var handle = _noPersistHandle.Get(context);
handle.Exit(context);
}

#endregion
}

正如您从代码中看到的那样,我进行了如下调用:phone.WinSipItf.DoSipRegister有效吗?我认为所有状态机都在与构造 WinSipItf 对象的线程不同的线程上执行...多余的说我对此一无所获...我什至无法中断 Execute 或 CacheMetadata。不确定此时该做什么。值得一提的是,我的 xaml 图已经构建完成,但我试图通过构建此自定义事件仅实现初始状态及其向空闲状态的转换...

也许我应该从一个简单的问题开始:当我在初始状态条目上删除注册事件时,我收到“未提供所需事件参数 'winSipItf' 的值”警告。我检查了所有代码,但不明白为什么。我错过了什么?

最佳答案

首先,由于您是 Workflow 的新手,您可能想要执行 Introduction to State Machine Hands On Lab .

其次 - 我有一个演示如何支持回调的示例应用程序(是的,工作流在不同的线程上执行)Windows Workflow Foundation (WF4) - Activity Callbacks and Event Handlers .

关于c# - WF4 中的状态机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7590444/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com