2012-09-05 240 views
0

它是這個問題的後續。使用線程池

https://stackoverflow.com/questions/12260170/how-to-make-a-threadpool-to-be-nonblocking

我一直在使用接口來實現它。我已經使用操作/刪除&使用接口非阻塞。是否有任何其他方式在.net中,我可以使下面的一段代碼nonblocking?接口實現如下。在任何時間點,我應該只有三個功能主,FuncA & FuncB

如果有人可以提供幫助。它會非常感激。謝謝。

using System; 
using System.Threading; 

namespace ConsoleApplication2 
{ 
    public interface IOperation 
    { 
     void CallBack(int i); 
    } 

    public class FuncBCalculation 
    { 
     public int N { get { return _n; } } 
     private int _n; 

     public int MyValue { get; set; } 
     public FuncBCalculation(int n) 
     { 
      _n = n; 
     } 

     // Wrapper method for use with thread pool. 
     public void FuncB(object context) 
     { 
      IOperation FuncBcallback = (IOperation)context; 
      Thread.Sleep(5); 
      MyValue = _n + 2; 
      FuncBcallback.CallBack(MyValue); 
     } 
    } 

    public class ActualClass : IOperation 
    { 
     int Finalvalue = 0; 
     public static IOperation MainThreadCallBack { get; set; } 

     public void FuncA(int input, int i, IOperation callback) 
     { 
      input += 1; 
      var f = new FuncBCalculation(input); 
      MainThreadCallBack = callback; 
      IOperation op = new ActualClass(); 
      ThreadPool.QueueUserWorkItem(f.FuncB, op); 

     } 

     //Method for callback operation 
     public void CallBack(int i) 
     { 
      Finalvalue = i + 3; 
      if (MainThreadCallBack != null) 
       MainThreadCallBack.CallBack(Finalvalue); 
     } 
    } 


    public class ThreadPoolExample : IOperation 
    { 
     static void Main() 
     { 
      ActualClass actualCall; 
      const int TotalLoopCount = 1000; 
      int input = 11; 
      Console.WriteLine("launching {0} tasks...", TotalLoopCount); 
      for (int i = 0; i < TotalLoopCount; i++) 
      { 
       IOperation op = new ThreadPoolExample(); 
       actualCall = new ActualClass(); 
       actualCall.FuncA(input, i, op); 
      } 
      Console.ReadKey(); 
     } 

     //Method for callback operation for the main thread 
     public void CallBack(int i) 
     { 
      Console.WriteLine("The final Result is {0}", i); 
     } 

    } 

} 
+0

你還必須定義'非阻塞'。並嘗試提供一個有些現實的用例和/或描述。以前因爲很好的理由而關閉。請注意,改進後可重新打開。 –

+0

可能重複[如何使一個線程池是非阻塞?](http://stackoverflow.com/questions/12260170/how-to-make-a-threadpool-to-be-nonblocking) –

+0

@HenkHolterman - 你可以看到我以前的帖子,使用waitone ..!我做了一個線程操作,但FuncA被阻塞,直到FuncB處理結果&在FuncA中我正在做一些基於reult的操作,然後我將它發送回主線程。在Marc Gravell的幫助下,我們設法使用Action/delegates/interfaces刪除阻塞。我正在尋找一種方式.net仍然有可能使其無阻塞。你知道任何方式請讓我知道。謝謝。! – Bala

回答

0
public class State 
{ 
    public int input { get; set; } 
    public int result { get; set; } 
    //public static int ThreadCount { get; set; } 
    public bool FuncBSignalON { get; set; } 
    //public static bool FuncAThreadON { get; set; } 
    //public int TotalLoopCount { get; set; } 
    //public int ThreadID { get; set; } 
} 


public class MainClass 
{ 
    public static void FuncB(Object stateObject) 
    { 
     State state = stateObject as State; 
     state.input += 2; 
     state.FuncBSignalON = true; 
     ThreadPool.QueueUserWorkItem(new WaitCallback(FuncA), state); 
    } 

    public static void FuncA(Object stateObject) 
    { 
     State state = (State)stateObject; 
     if (!state.FuncBSignalON) 
     { 
      state.input += 1; 
      ThreadPool.QueueUserWorkItem(new WaitCallback(FuncB), state); 
     } 
     else 
     { 
      state.result = state.input + 3; 
      //FinalResult.Add(state.result); 
      string[] stateResult = new string[1]; 
      stateResult[0] = state.result.ToString(); 
      //State.ThreadCount--; 
      Main(stateResult); 
     } 
    } 

    static void Main(string[] args) 
    { 
     if (args.Count() == 0) 
     { 
      int TotalLoopCount =1000; 
      for (int i = 0; i < TotalLoopCount; i++) 
      { 
       State FuncAstate = new State(); 
       FuncAstate.input = 11; 
       //FuncAstate.TotalLoopCount = TotalLoopCount; 
       //State.ThreadCount++; 
       ThreadPool.QueueUserWorkItem(new WaitCallback(FuncA), FuncAstate); 
      } 
     } 
     else 
     { 
      Console.WriteLine(args[0]); 
     } 
     Console.ReadKey(); 
    } 

} 

明白了最後。

0

就可以實現它是這樣的:

class _Program 
{ 
    public static int MyInput { get; set; } 

    static void Main(string[] args) 
    { 
     int input = 11; 
     for (int i = 0; i < 1000 ; i++) 
     { 
      MyInput = input + 1; 
      FuncA(delegate(IAsyncResult result) 
      { 
       AsyncResult<Int32> funcBResult = result as AsyncResult<Int32>; 
       Int32 value = funcBResult.EndInvoke() + 3; 
       Console.WriteLine("Final value: " + value); 
      }, null); ; // using callback method 
     } 
     Console.ReadLine(); 
    } 

    public static IAsyncResult FuncA(AsyncCallback callback, Object state) 
    { 
     AsyncResult<Int32> result = new AsyncResult<int>(callback, state); 
     ThreadPool.QueueUserWorkItem(FuncB, result); 
     return result; 
    } 

    public static void FuncB(Object asyncResult) 
    { 
     AsyncResult<Int32> result = asyncResult as AsyncResult<Int32>; 
     try 
     { 
      Int32 value = MyInput + 2; 
      result.SetAsCompleted(false, value); 
     } 
     catch (Exception ex) 
     { 
      result.SetAsCompleted(false, ex); 
     } 
    } 

} 
+0

有沒有人有更多的解決方案? – Bala

0

發現了另一個答案,但問題是這裏有一個機會,順序可能會感到困惑。首先加1然後在FuncB加2,然後在​​再加3!任何人都可以糾正我?

public class MainClass 
{ 
    public static List<int> finalResult = new List<int>(); 

    public static void FuncB(Object stateObject) 
    { 
      State state = stateObject as State; 
      state.result += 2; 
      MainClass.finalResult.Add(state.result); 
      State.ThreadCount--; 
    } 

    public static void FuncA(Object stateObject) 
    { 
     State state = (State)stateObject; 
     state.input += 1; 
     State.ThreadCount++; 
     ThreadPool.QueueUserWorkItem(new WaitCallback(FuncB), state); 
     state.result = state.input + 3; 
    } 

    static void Main() 
    { 
     int TotalLoopCount = 1000; 

     for (int i = 0; i < TotalLoopCount; i++) 
     { 
      State FuncAstate = new State(); 
      FuncAstate.input = 11; 
      FuncA(FuncAstate); 
     } 

     while (State.ThreadCount > 0) 
     { 
      Console.WriteLine("Waiting for all the threads to terminate. Still {0} no of threads available in memory", State.ThreadCount); 
      State.ThreadCount--; 
      continue; 
     } 


     for (int i = 0; i < MainClass.finalResult.Count(); i++) 
     { 
       Console.WriteLine("The final Result {0}", MainClass.finalResult[i]); 
     } 

     Console.ReadKey(); 

    } 
} 
public class State 
    { 
     //public ManualResetEvent eventWaitHandle { get; set; } 
     public int input { get; set; } 
     public int result { get; set; } 
     public int ThreadID { get; set; } 
     //public ThreadStart threadState { get; set; } 
     public static int ThreadCount { get; set; } 
    }