locked
RemoveBookmark: Bookmarks can only be removed by the activity instance that created them RRS feed

  • Question

  • I'm tring to build a custom activity called ReceiveDeviceMessageActivity which is continuesly receive event notification and invoke later actions and support break.

    but when I nest ReceiveDeviceMessageActivity and run, error prompt: Bookmarks can only be removed by the activity instance that created them.

    what should I do or any suggestion?

    code is as following

        public class ReceiveDeviceMessageActivity : NativeActivity
        {
            public ReceiveDeviceMessageActivity()
            {
            }
            [DefaultValue((string)null)]
            public ActivityAction<DeviceMessage> Body { getset; }
            Bookmark m_HandlerBookmark;

            protected override void Execute(NativeActivityContext context)
            {
                m_HandlerBookmark = context.CreateBookmark(OnMessageReceived, BookmarkOptions.MultipleResume | BookmarkOptions.NonBlocking);
                context.GetExtension<ReceiveDeviceMessageExtention>().Attach(m_HandlerBookmark);
                context.Properties.Add(BreakActivity.Key, context.CreateBookmark(OnBreak));
            }

            void OnMessageReceived(NativeActivityContext context, Bookmark bookmark, object value)
            {
                context.ScheduleAction<DeviceMessage>(Body, value as DeviceMessage);
            }
            void OnBreak(NativeActivityContext context, Bookmark bookmark, object value)
            {
                context.RemoveBookmark(m_HandlerBookmark);
            }
            protected override bool CanInduceIdle
            {
                get
                {
                    return true;
                }
            }

            protected override void CacheMetadata(NativeActivityMetadata metadata)
            {
                base.CacheMetadata(metadata);
                metadata.AddDefaultExtensionProvider<ReceiveDeviceMessageExtention>(() => new ReceiveDeviceMessageExtention());
            }
        }

     

        public class ReceiveDeviceMessageExtention : IWorkflowInstanceExtensionIDisposable
        {
            Dictionary<BookmarkEventHandler<MessageReceivedEventArgs>> m_BookmarkHandlers = new Dictionary<BookmarkEventHandler<MessageReceivedEventArgs>>();
            WorkflowInstanceProxy m_Instance;

            public void Attach(Bookmark bookmark)
            {
                if (!m_BookmarkHandlers.ContainsKey(bookmark))
                {
                    m_BookmarkHandlers[bookmark] = (sender, e) =>
                    {
                        m_Instance.BeginResumeBookmark(bookmark, e.Message, ar =>
                        {
                            m_Instance.EndResumeBookmark(ar);
                        }, null);
                    };
                    ECServerProxy.MessageReceived += m_BookmarkHandlers[bookmark];
                }
            }

            public IEnumerable<object> GetAdditionalExtensions()
            {
                return null;
            }

            public void SetInstance(WorkflowInstanceProxy instance)
            {
                m_Instance = instance;
            }


            public void Dispose()
            {
                foreach (var bookmark in m_BookmarkHandlers.Keys)
                {
                    ECServerProxy.MessageReceived -= m_BookmarkHandlers[bookmark];
                }
                m_BookmarkHandlers.Clear();
            }
        }
        public sealed class BreakActivity : NativeActivity
        {
            public BreakActivity()
            {
                DisplayName = "Break";
            }
            public const string Key = "BreakActivity";

            protected override void Execute(NativeActivityContext context)
            {
                Bookmark bookmark = context.Properties.Find(Key) as Bookmark;
                context.ResumeBookmark(bookmark, null);
            }
            protected override bool CanInduceIdle
            {
                get
                {
                    return false;
                }
            }
        }
    <Activity mc:Ignorable="sap" x:Class="{x:Null}" sap:VirtualizedContainerService.HintSize="344,644" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:hrr="clr-namespace:HUS.RE.RuleLibrary;assembly=HUS.RE.RuleLibrary" xmlns:hrrm="clr-namespace:HUS.RE.RuleCommon.Models;assembly=HUS.RE.RuleCommon" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <Sequence sap:VirtualizedContainerService.HintSize="304,604" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">
        <sap:WorkflowViewStateService.ViewState>
          <scg:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
          </scg:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <hrr:ReceiveDeviceMessageActivity DisplayName="ReceiveDeviceMessage" sap:VirtualizedContainerService.HintSize="282,480">
          <hrr:ReceiveDeviceMessageActivity.Body>
            <ActivityAction x:TypeArguments="hrrm:DeviceMessage">
              <ActivityAction.Argument>
                <DelegateInArgument x:TypeArguments="hrrm:DeviceMessage" Name="message" />
              </ActivityAction.Argument>
              <Sequence sap:VirtualizedContainerService.HintSize="252,383">
                <sap:WorkflowViewStateService.ViewState>
                  <scg:Dictionary x:TypeArguments="x:String, x:Object">
                    <x:Boolean x:Key="IsExpanded">True</x:Boolean>
                  </scg:Dictionary>
                </sap:WorkflowViewStateService.ViewState>
                <hrr:ReceiveDeviceMessageActivity DisplayName="ReceiveDeviceMessage" sap:VirtualizedContainerService.HintSize="230,197">
                  <hrr:ReceiveDeviceMessageActivity.Body>
                    <ActivityAction x:TypeArguments="hrrm:DeviceMessage">
                      <ActivityAction.Argument>
                        <DelegateInArgument x:TypeArguments="hrrm:DeviceMessage" Name="message" />
                      </ActivityAction.Argument>
                      <hrr:BreakActivity DisplayName="Break" sap:VirtualizedContainerService.HintSize="200,100" />
                    </ActivityAction>
                  </hrr:ReceiveDeviceMessageActivity.Body>
                </hrr:ReceiveDeviceMessageActivity>
                <hrr:BreakActivity DisplayName="Break" sap:VirtualizedContainerService.HintSize="230,22" />
              </Sequence>
            </ActivityAction>
          </hrr:ReceiveDeviceMessageActivity.Body>
        </hrr:ReceiveDeviceMessageActivity>
      </Sequence>
    </Activity>
    Wednesday, January 26, 2011 3:18 AM

Answers

  • Thanks for your question.

    I believe the issue is that your m_HandlerBookmark is tied to your activity definition, rather than your activity instance. If you make that a Variable, rather than a member of the class, you should be able to make this work.

     

    • Marked as answer by Andrew_Zhu Wednesday, February 2, 2011 9:39 AM
    Tuesday, February 1, 2011 7:19 PM

All replies

  • Which line of code is actually throwing that exception?
    Tim

    Sunday, January 30, 2011 5:19 AM
  • Thanks for your question.

    I believe the issue is that your m_HandlerBookmark is tied to your activity definition, rather than your activity instance. If you make that a Variable, rather than a member of the class, you should be able to make this work.

     

    • Marked as answer by Andrew_Zhu Wednesday, February 2, 2011 9:39 AM
    Tuesday, February 1, 2011 7:19 PM