Действительно ли возможно поместить обработчик событий на другой поток вызывающей стороне?

Использование -

dd <- data.frame(x=c(3,4,5),id=c('A','B','C'))
foo  <- function(x,a){
  df <- data.frame(
    "id" = character()
    ,"y" = numeric()
  )

  for(i in 1:2)
  {
    for(j in 1:2)
    {
      y<-x+i+j 
      df<- rbind(df, data.frame(
        "id" = a
        ,"y" = y
      )
      )

    }

  }

  # Replace with group_by, filter, max
  result<-df%>% 
    group_by(id)%>%
    filter(y == max(y))
  return(result$y)
}

dd%>% mutate(t=foo(dd$x, dd$id))

Вывод

  x id t
1 3  A 7
2 4  B 8
3 5  C 9

Объяснение

Вы просто должны были позаботиться о последний фрагмент result для group_by значений id и выборки всех строк, которые имели максимум y для каждой группы

10
задан Rob Gray 28 January 2009 в 03:32
поделиться

6 ответов

Возможно, Вы могли заставить DoSyncTask запускать объект - таймер, который проверяет на значение Вашей переменной данных в некотором соответствующем интервале. После того как данные имеют значение, у Вас мог затем быть другой огонь события, чтобы сказать Вам, что данные теперь имеют значение (и отключите таймер, конечно).

Довольно ужасный взлом, но это могло работать... в теории.

Извините, это является лучшим, я могу придумать наполовину спящий. Время ложиться спать...

2
ответ дан 4 December 2019 в 02:52
поделиться

Я испытал некоторые затруднения в последнее время из-за совершения асинхронных звонков и событий в потоках и возврате их к основному потоку.

Я использовал SynchronizationContext для отслеживания вещи. (Псевдо) код ниже показывает то, что работает на меня в данный момент.

SynchronizationContext context;

void start()
{
    //First store the current context
    //to call back to it later
    context = SynchronizationContext.Current; 

    //Start a thread and make it call
    //the async method, for example: 
    Proxy.BeginCodeLookup(aVariable, 
                    new AsyncCallback(LookupResult), 
                    AsyncState);
    //Now continue with what you were doing 
    //and let the lookup finish
}

void LookupResult(IAsyncResult result)
{
    //when the async function is finished
    //this method is called. It's on
    //the same thread as the the caller,
    //BeginCodeLookup in this case.
    result.AsyncWaitHandle.WaitOne();
    var LookupResult= Proxy.EndCodeLookup(result);
    //The SynchronizationContext.Send method
    //performs a callback to the thread of the 
    //context, in this case the main thread
    context.Send(new SendOrPostCallback(OnLookupCompleted),
                 result.AsyncState);                         
}

void OnLookupCompleted(object state)
{
    //now this code will be executed on the 
    //main thread.
}

Я надеюсь, что это помогает, поскольку это решило проблему для меня.

3
ответ дан 4 December 2019 в 02:52
поделиться

Я разработал решение асинхронного для синхронизации проблемы, по крайней мере, с помощью всех классов.NET.

http://geekswithblogs.net/rgray/archive/2009/01/29/turning-an-asynchronous-call-into-a-synchronous-call.aspx

Это все еще не работает с COM. Я подозреваю из-за поточной обработки STA. Событие, сгенерированное компонентом.NET, который размещает COM OCX, никогда не обрабатывается моим рабочим потоком, таким образом, я получаю мертвую блокировку на WaitOne ().

кто-то еще может ценить решение хотя :)

2
ответ дан 4 December 2019 в 02:52
поделиться

Вы почти получили его. Вам нужен метод DoTask для работы другого потока, таким образом, вызов WaitOne не будет препятствовать тому, чтобы работа была сделана. Что-то вроде этого:

Action<int, int> doTaskAction = t.DoTask;
doTaskAction.BeginInvoke(latitude, longitude, cb => doTaskAction.EndInvoke(cb), null);
taskDone.WaitOne();
0
ответ дан 4 December 2019 в 02:52
поделиться

Если Задачей является компонент WinForms, она могла бы очень знать о поточной обработке проблем и Вызывать обработчик событий на основной поток - который, кажется, то, что Вы видите.

Так, могло бы случиться так, что это полагается на случай насоса сообщения или что-то. Приложение. Выполненный имеет перегрузки, которые являются для приложений для не-GUI. Вы могли бы рассмотреть то, чтобы заставлять поток запустить и накачать, чтобы видеть, устраняет ли это проблему.

Я также рекомендовал бы использовать Отражатель, чтобы заставить взгляд на исходный код компонента выяснять то, что он делает.

0
ответ дан 4 December 2019 в 02:52
поделиться

Мой комментарий к ответу W Scott кажется немного загадочным после того, как я перечитал его. Таким образом позвольте мне быть более явным:

while( !done )
{
    taskDone.WaitOne( 200 );
    Application.DoEvents();
}

WaitOne (200) вызовет, он для возврата управления UI распараллеливает 5 раз в секунду (можно скорректировать это, как Вы желаете). DoEvents () вызов сбросит очередь событий окон (тот, который обрабатывает всю обработку событий окон как рисование, и т.д.). Добавьте двух участников к своему классу (один флаг bool, "сделанный" в этом примере и данных возврата "улица" в Вашем примере).

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

0
ответ дан 4 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: