Фоновый агент notifyComplete () после HTTPRequest - PullRequest
3 голосов
/ 05 декабря 2011

Я хочу создать HTTPRequest для периодической задачи в фоновом агенте Windows Phone 7. Для простоты я просто хочу вызвать метод общего класса между backgroundAgent и приложением.

Общий метод - простой HTTPRequest.

На SharedClass.cs makeTheRequest ()

public static void makeTheRequest(){
    var request = (HttpWebRequest)WebRequest.Create(new Uri("http://foo.bar"));
    request.BeginGetResponse(r =>
    {
         NotifyComplete();
    }, request);
}

Я не могу вызвать notifyComplete () здесь, потому что не входит в область действия.

На BackgroundAgent.cs onInvoke ()

protected override void OnInvoke(ScheduledTask task)
{
     if (task is PeriodicTask)
     {
          SharedClass.makeTheRequest();

          NotifyComplete(); 
     }
}

Когда я вызываю это здесь, вероятно, makeTheRequest () никогда не завершается, потому что процесс завершается до того, как завершится

Я прочитал кое-что о библиотеке Taks Parallel , но я не знаю, правильный ли это способ или нет.

спасибо

Ответы [ 3 ]

4 голосов
/ 05 декабря 2011

Я бы изменил ваш метод makeTheRequest(), чтобы вы могли передать его Action для запуска после завершения запроса.

В вызове от оператора вы можете включить вызов на NotifyComplete(), ноиз приложения вы этого не делаете.

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

Обновление

Пример:

protected override void OnInvoke(ScheduledTask task)
{
    if (task is PeriodicTask)
    {
        SharedClass.makeTheRequest(this.NotifyComplete);
    }
}

public class SharedClass
{
    public static void makeTheRequest(Action callback)
    {
        var request = (HttpWebRequest)WebRequest.Create(new Uri("http://foo.bar"));
        request.BeginGetResponse(r => callback.Invoke(), request);
    }
}
3 голосов
/ 24 марта 2012
  1. После выхода из основного потока bgAgent запрос HttpWebRequest будет уничтожен.
  2. Здесь мы должны использовать синхронный запрос HttpWebRequest, но мы не можем, потому что MS убрала их из замаскированной платформы.
  3. Мы должны имитировать поведение блокировки потоков, используя объекты синхронизации потоков, такие как ManualResetEvent.

    protected override void OnInvoke(ScheduledTask task)
    {
        var evnt = new ManualResetEvent(false);//initialize to unsignalled state (false)
        var request = (HttpWebRequest)WebRequest.Create(new Uri("http://foo.bar"));
        request.BeginGetResponse(r =>
        {
           //do work here
           evnt.Set();//signal main thread to continue 
        }, request);

        evnt.WaitOne();//block execution of main thread

        NotifyComplete();
        return;
    }

Таким образом, ни один из основных потоков не завершится, и NotifyComplete не будет вызвано до того, как вы закончите свою работу. Вы должны сделать это WaitOne с тайм-аутом (около 25 секунд), чтобы ваша задача не была убита и (что еще хуже) незапланированной из-за ограничения в 30 секунд. Это усложнит ситуацию, так как вам нужно будет защитить оба потока (основной и http) друг от друга. Проблема evnt.Close () здесь также не отображается. Основной поток может закрыть дескриптор до того, как http завершит работу и попытается установить (). Или вы можете рассчитывать на сборку мусора Нужно ли вызывать Close () для ManualResetEvent?

(кстати, ManualResetEvent не имеет ничего общего с концепцией события C #. Это и событие в смысле Win32, из той же банды, что и Mutex и Semaphore).

1 голос
/ 07 февраля 2012

Вы ДОЛЖНЫ использовать Delegate

В SharedClass.cs

 public delegate void MyDelegate();
 public MyDelegate MyUpdate;

В BackgroundAgent.cs Возможно

void UpdateLiveTile() { ..... NotifyComplete(); }

В BackgroundAgent.cs onInvoke ()

var cs = new SharedClass();
cs.MyUpdate= new SharedClass.MyDelegate(UpdateLiveTile);
cs.makeTheRequest();

В публичном статическом void makeTheRequest ()

public static void makeTheRequest()
{
   var request ....
   request.BeginGetResponse(r =>
   {
      .........
      MyUpdate();
   }, request
...