如何用Task.Factory.StartNew()替换ThreadPool.QueueUserWorkItem()?

时间:2013-03-14 15:05:54

标签: c# multithreading linq lambda task-parallel-library

在C#3.0中使用下面的工作代码,如何将其转换为C#4.0替换该行

ThreadPool.QueueUserWorkItem(LongGetOrAdd(dict, 1));

通过

Task task1 = Task.Factory.StartNew(//?

C#3.0控制台应用程序的完整代码:

using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
class Program
{
  static void Main()
  {
    var dict = new ConcurrentDictionary<int, string>();
    ThreadPool.QueueUserWorkItem(LongGetOrAdd(dict, 1));

//???????
//Task task1 = Task.Factory.StartNew((Action)(LongGetOrAdd(dict, 1));

    Console.WriteLine("Press enter to continue:");
    foreach (var a in dict)
    Console.WriteLine("dict.Key = {0}  dict.Value = {1}  ", a.Key, a.Value);


    Console.ReadLine();
  }
  private static WaitCallback LongGetOrAdd(ConcurrentDictionary<int, string> dict, int index)
  {
    return o => dict.GetOrAdd
    (index, 
     i =>
       {
         Console.WriteLine("From method LongGetOrAdd()!");
         Thread.SpinWait(1000);
         return i.ToString();
       }
    );
  }
}

产生输出:

Press enter to continue:
From method LongGetOrAdd()!

dict.Key = 1  dict.Value = 1

2 个答案:

答案 0 :(得分:2)

应该这样做。

    var c = LongGetOrAdd(dict, 1);

    var t = Task.Factory.StartNew(() => c.Invoke(null));

    Task.WaitAll(task);
    Console.ReadLine();

答案 1 :(得分:0)

您只需要更改LongGetOrAdd返回的委托类型并调用另一种方法。

您还需要从lambda中删除该参数,因为您实际上并没有传递任何信息。

只需查看Task.Factory.StartNew的签名,编译器/智能感知就清楚地表明了这一切。

private static Action LongGetOrAdd(ConcurrentDictionary<int, string> dict, int index)
{
    return () => dict.GetOrAdd
    (index,
     i =>
     {
         Console.WriteLine("======!");
         Thread.SpinWait(1000);
         return i.ToString();
     }
    );
}
private static void Main()
{
    var dict = new ConcurrentDictionary<int, string>();
    Task.Factory.StartNew(LongGetOrAdd(dict, 1));

    Console.WriteLine();
    Console.WriteLine("press any key to exit . . .");
    Console.ReadKey();
}