2012-03-21 6 views
5

У меня есть класс, который сохраняет информацию о регистрации в базе данных (в сообщении NServiceBus Handle).Условно запустить методы класса в отдельном потоке

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

Однако, как только он запускает внешнюю привязку к фактическим данным из NServiceBus, он должен находиться в одном потоке.

Вот несколько примеров кода:

public class MyExample 
{ 

    public void LogSomeStuff(Stuff stuff) 
    { 
     using (MoveOutsideTransaction()) 
     { 
     // Do Method Stuff here 
     dataAccess.SaveChanges(); 
     } 
    } 


    public void LogSomeOtherStuff(Stuff stuff) 
    { 
     using (MoveOutsideTransaction()) 
     { 
     // Do Other Method Stuff here 
     dataAccess.SaveChanges(); 
     } 
    } 

    private IDisposable MoveOutsideTransaction() 
    { 
     if (loggingOutsideTransaction) 
      return new TransactionScope(TransactionScopeOption.Suppress); 

     return null; 
    } 
} 

мне интересно, если есть способ использовать мою сделку условно также условно переместить работает в другом потоке. (Но только тогда, когда он подавляет сделку.)

ответ

2

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

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

Вот как это работает.

public class DedicatedThread 
{ 
    private BlockingCollection<Action> actions = new BlockingCollection<Action>(); 

    public DedicatedThread() 
    { 
    var thread = new Thread(
    () => 
     { 
     while (true) 
     { 
      Action action = actions.Take(); 
      action(); 
     } 
     }); 
    } 

    public void SubmitAction(Action action) 
    { 
    actions.Add(action); 
    } 
} 

И вы можете использовать его вот так.

if (loggingOutsideTransaction) 
{ 
    // Execute asynchronously on a dedicated thread. 
    dedicatedThread.SubmitAction(yourActionDelegate); 
} 
else 
{ 
    // Execute synchronously. 
    yourActionDelegate(); 
} 
+0

Это выглядит великолепно, но многие из моих методов имеют несколько параметров. Большинство из них - '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' (Кажется, это просто вызов метода, но не позволяет параметры с каждым вызовом.) – Vaccano

+2

@Vaccano: Вместо этого вы можете использовать «Действие ». Или при создании делегата 'Action' через лямбда-выражение вы можете сделать закрытие переменной. –

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