Pergunta

Trabalhar em um projeto onde um conjunto sequencial de métodos deve ser executado a cada x segundos.No momento, tenho os métodos contidos em outro "método pai" e apenas os chamo sequencialmente, logo após o outro.

class DoTheseThings()
{
    DoThis();
    NowDoThat();
    NowDoThis();
    MoreWork();
    AndImSpent();
}

Cada método deve ser executado com êxito sem lançar uma exceção antes que a próxima etapa possa ser executada.Então agora envolvi cada um desses métodos com um while e try..catch, então no catch execute esse método novamente.

while( !hadError )
{
    try
    {
         DoThis();
    }
    catch(Exception doThisException )
    {
         hadError = true;
    }

}

Parece fedorento e não muito seco.Existe uma maneira melhor de fazer isso, então não estou agrupando nenhuma nova funcionalidade nos mesmos métodos.Algum tipo de coleção de delegados não é a maneira correta de implementar isso?

Existe uma solução mais "adequada"?

Foi útil?

Solução

Action[] work=new Action[]{new Action(DoThis),   new Action(NowDoThat),    
    new Action(NowDoThis),    new Action(MoreWork),    new Action(AndImSpent)};
int current =0;
while(current!=work.Length)
{
   try
   {
      work[current]();
      current++;
   }
   catch(Exception ex)
   {
      // log the error or whatever
      // maybe sleep a while to not kill the processors if a successful execution depends on time elapsed  
   }
}

Outras dicas

Não é algum tipo de coleção de delegados a maneira correta de implementar isso?

O delegado é uma maneira possível de resolver esse problema.

Basta criar um delegado algo como:

delegado público void workdelegate ();

e coloque -os na lista de Arrays, que você pode iterar.

Eu tenho uma crença religiosa pessoal de que você não deve capturar o sistema.Exception, ou mais precisamente, você deve pegar apenas as exceções que sabe como lidar.

Dito isto, vou assumir que cada um dos métodos que você está chamando estão fazendo algo diferente e pode resultar em diferentes exceções sendo jogadas. O que significa que você provavelmente precisaria ter manipuladores diferentes para cada método.

Se você segue minha religião também e a segunda afirmação é verdadeira, não está repetindo o código desnecessariamente. A menos que você tenha outros requisitos, minhas recomendações para melhorar seu código seriam:

1) Coloque a captura de tentativa em cada método, não em torno de cada chamada de método.

2) Peça às capturas dentro de cada método capturar apenas as exceções que você conhece.

http://blogs.msdn.com/fxcop/archive/2006/06/14/631923.aspx http://blogs.msdn.com/oldnewthing/archive/2005/01/14/352949.aspx http://www.joelonsoftware.com/articles/wrong.html

HTH ...

seu exemplo parece ok ..é seco, mas fará bem o trabalho!!na verdade, se esses métodos executarem acesso ao banco de dados.você pode usar a transação para garantir a integridade ...

se você estiver lidando com variáveis ​​​​compartilhadas para programas multi threader.é mais limpo usar a sincronização.a coisa mais importante na codificação é que você escreva o código adequado...que tem menos bugs..e fará a tarefa corretamente.

public void DoTheseThings()
{
    SafelyDoEach( new Action[]{
        DoThis,
        NowDoThat,
        NowDoThis,
        MoreWork,
        AndImSpent
    })
}

public void SafelyDoEach( params Action[] actions )
{
    try
    {
        foreach( var a in actions )
            a();
    }
    catch( Exception doThisException )
    {
        // blindly swallowing every exception like this is a terrible idea
        // you should really only be swallowing a specific MyAbortedException type
        return;
    }
}

Qual seria a razão pela qual um erro estava ocorrendo?

Se esse fosse um problema de recurso, como acesso a algo como uma conexão ou objeto, convém ver o uso de monitores, semáforos ou apenas bloqueio.

lock (resource) 
{
    Dosomething(resource);
}

Dessa forma, se um método anterior estiver acessando o recurso, você poderá esperar até que ele libere o recurso para continuar.

Idealmente, você não deve executar um loop para executar algo cada vez que falhar. Está falhando, você gostaria de saber sobre o problema e corrigi -lo. Ter um loop para sempre continuar tentando não é o caminho certo para ir aqui.

Eu faria o que ovidiu -pacurar sugere, só eu usaria um foreach Faça um loop e saia lidando com índices de matriz até o compilador.

Abordagem simples de delegado:

Action<Action> tryForever = (action) => { 
   bool success;
   do {
     try {
       action();
       success = true;
     } catch (Exception) {
       // should probably log or something here...
     }
   } while (!success);
};

void DoEverything() {
   tryForever(DoThis);
   tryForever(NowDoThat);
   tryForever(NowDoThis);
   tryForever(MoreWork);
   tryForever(AndImSpent);
}

Abordagem de pilha:

void DoEverything() {
  Stack<Action> thingsToDo = new Stack<Action>(
    new Action[] { 
      DoThis, NowDoThat, NowDoThis, MoreWork, AndImSpent 
    }
  );

  Action action;
  while ((action = thingsToDo.Pop()) != null) {
     bool success;
     do {
       try {
         action();
         success = true;
       } catch (Exception) {
       }
     } while (!success);
  }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top