2012-02-13 3 views
2

Редактировать: я обновил свой код. Будет ли это достигать того, к чему я стремлюсь?Как передать действие на фабрику задач со слабой ссылкой на цель

У меня есть рабочий набор методов для асинхронного вызова методов, но у меня есть конкретная проблема с ссылками, которые я передаю через лямбда. В частности, у меня есть (дочернее) окно, которое запускает операцию и регистрирует обратный вызов. Как и следовало ожидать, даже когда я закрываю это окно, он все равно вызывается.

Что я хочу сделать, это передать своеобразную «слабую ссылку» или создать слабую ссылку из входящего действия.

Thhis путь я строй моих действий (пример коды):

static Action CreateNewAction(Action call, Action<SomeArg> callback, 
    Dispatcher dispatcher) 
{ 
    return delegate { 
     try 
     { 
      call(); 

      var target = callback.Target 
      if(target != null) 
       dispatcher.Invoke(callback, new SomeArg()); 
    } 
     catch (Exception ex) 
     { 
      // handle the ex in some way.. 
     } 
    }; 
} 

И это как задача завод называет это:

var t = Task.Factory.StartNew(CreateNewAction(call, callback, dispatcher)) 

И это, как я бы назвал это (вызов просто базирует как действие, так и обратный вызов до фабрики задач, как показано выше):

WeakReference wr = new WeakReference(myTarget); 
StartMyTaskAsync(someAction, ((MyTargetClass)wr.Target).SomeCompletedFunc); 
+0

И что именно происходит, когда вы вызываете это действие в закрытом окне? – svick

+0

@svick hm Хорошо, я просто строю его так мало, что сейчас происходит, но он возвращает данные, и это, вероятно, можно установить на datacontext или что-то, что я думаю. – UrbanEsc

+0

Итак, почему это проблема, когда это происходит? – svick

ответ

0

Проблема исходит от этой линии:

StartMyTaskAsync(someAction, ((MyTargetClass)wr.Target).SomeCompletedFunc); 

В частности, эта часть:

((MyTargetClass)wr.Target).SomeCompletedFunc 

Вы материализации Цель WeakReference получить метод, который ссылается на лямбда/делегатом задолго до того, вы хотите на самом деле проверьте, отпустил ли WeakReference номер Target.

Что вы действительно хотите сделать, это передать оболочку для вашего делегата, что-то вроде этого (вы не указали подпись SomeCompletedFunc, так что я точно не знаю, как будет выглядеть звонок, я предполагаю, что это метод без параметров недействительного для целей данного вопроса):

StartMyTaskAsync(someAction,() => { 
    // Check the weak reference. If null, return. 
    var target = wr.Target as MyTargetClass; 

    // If null, return. 
    if (target == null) return; 

    // If not null, call. 
    target.SomeCompletedFunc(); 
}); 

Таким образом, вы проверяете Target в WeakReferenceв то время вы хотите сделать вызов метода, а не при назначении обратного вызова.

Смежные вопросы