2012-09-05 151 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; } 
    }