Предоставление переменных NativeActivity конструктору рабочих процессов

У меня есть NativeActivity, который содержит Activity тело. Цель этого действия - предоставить ресурс на время дочернего действия как Variable. Проблема, с которой я столкнулся, заключается в том, что Variable нельзя использовать вне деятельности. Я буду использовать StreamReader в качестве примера ресурса.

ResourceActivity.cs:

[Designer(typeof(ResourceActivityDesigner))]
public sealed class ResourceActivity : NativeActivity
{
    [RequiredArgument]
    public InArgument<string> Path { get; set; }

    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public Activity Body { get; set; }

    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public Variable<StreamReader> Resource { get; set; }

    public ResourceActivity()
    {
        this.Resource = new Variable<StreamReader>
        {
            Default = null,
            Name = "reader"
        };
    }

    protected override void CacheMetadata(NativeActivityMetadata metadata)
    {
        if (this.Path != null) metadata.AddArgument(this.Path);
        if (this.Body != null) metadata.AddChild(this.Body);
        if (this.Resource != null) metadata.AddVariable(this.Resource);
    }

    protected override void Execute(NativeActivityContext context)
    {
        this.Resource.Set(context, new StreamReader(this.Path.Get(context)));
        context.ScheduleActivity(this.Body, new completionCallback(Done), new FaultCallback(Faulted));
    }

    private void Done(NativeActivityContext context, ActivityInstance instance)
    {
        var reader = this.Reader.Get(context);
        if (reader != null) reader.Dispose();
    }

    private void Faulted(NativeActivityFaultContext context, Exception ex, ActivityInstance instance)
    {
        var reader = this.Reader.Get(context);
        if (reader != null) reader.Dispose();
    }
}

Я не могу просмотреть «Ресурс» или «Читатель» в списке переменных в конструкторе рабочих процессов. Я что-то упустил в CacheMetadata?


person user7116    schedule 09.06.2010    source источник


Ответы (2)


Похоже, ответом было добавление Collection<Variable> к классу. CacheMetadata было ненужным.

[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public Collection<Variable> Variables { get; private set; }

public ResourceActivity()
{
    this.Resource = new Variable<StreamReader> { Default = null, Name = "reader" };
    this.Variables = new Collection<Variable>(new [] { this.Resource });
}

РЕДАКТИРОВАТЬ: Нет, теперь возникает ошибка, в которой говорится, что переменная определена несколько раз. Если я не добавлю ресурс в коллекцию переменных, он просто не появится ...

ИЗМЕНИТЬ №2: Я отправил это как ошибку в Microsoft Connect, и мне сказали, что это известная ошибка, , но это не предназначено для исправления в VS 2010. Это был отложен.

person user7116    schedule 10.06.2010
comment
Ваша первая ошибка связана с тем, что переменные сериализуются в xaml, поэтому, когда он десериализуется, ваш конструктор сначала добавляет переменную, а затем десериализованный добавляется в коллекцию, вызывая эту ошибку. Переместите этот код в IActivityTemplateFactory.Create, и у вас не будет этой ошибки. Ошибка, о которой вы сообщили, кажется другой, когда Activity не может создавать и предоставлять переменные для своих дочерних элементов, а также иметь к ним доступ. Какой-то прицел БС. Имея ту же проблему. Когда-нибудь находили обходной путь? - person ; 10.06.2011
comment
Кстати, я действительно думаю о создании фиктивного дочернего действия, единственной целью которого является обновление переменной. Эффинг. Нелепый. - person ; 10.06.2011
comment
@Will: мы пошли и реструктурировали это приложение из-за огромного разочарования в WF и отсутствия какой-либо согласованной документации по чему-либо, кроме тривиального. Поддержка MS для WF настолько отвратительна, что мы отказались от этой части приложения из-за отсутствия достаточных обходных путей. Если вы добавите свой бит о сериализации / десериализации в качестве ответа, я отмечу его как принятый. - person user7116; 10.06.2011
comment
Нет, это к. Я не так сильно разбираюсь в WF4, как вы. Удалось делать действительно сложные и впечатляющие вещи. Но это новый продукт, и поэтому информации о нем не так много. Я согласен, что они могут внести больше ясности в документы MSDN ... По многим вопросам. - person ; 11.06.2011

Вам нужно определить ваше тело как тип ActivityAction вместо Activity, если вы хотите поделиться переменной между самим действием и дочерними элементами. См. это сообщение в блоге Мэтта Винклера.

person Maurice    schedule 10.06.2010