所以我有2个问题
其实,我看到有三。这是你的第一个问题(缺少问号不会妨碍它成为问题:)):
用户如何确定哪个进度是哪个函数调用的。
你怎么想的用户来确定?随着你发布的代码,它根本不可能。有很多种的,你可以解决这个问题的方法,但如果你是在谈论重新使用相同的委托实例,你就必须修改调用方法:
public static Task LongOperationAsync(List<String> names, Action<String> progress, string id)
{
return Task.Factory.StartNew(() =>
{
foreach (var item in names)
{
// do some long operation
progress($"{id}: {item.ToUpper()}");
}
});
}
static void Main(string[] args)
{
var friends = new List<String>() {"joey","ross","chandler","monica","phoebe","rachel" };
var scienfelds = new List<String>() { "Jerry", "kramer", "george", "elaine" };
Action<String> resultProcessor = (result) =>
{
// process the result. let's say update the UI as and when results arrive
Console.WriteLine(result);
};
var task1 = LongOperationAsync(friends, resultProcessor, "task1");
var task2 = LongOperationAsync(scienfelds, resultProcessor, "task2");
Task.WaitAll(task1, task2);
Console.ReadLine();
}
或相关的选择,如果你想回调本身要能知道哪个任务的进展情况是:
public static Task LongOperationAsync(List<String> names, Action<String, String> progress, string id)
{
return Task.Factory.StartNew(() =>
{
foreach (var item in names)
{
// do some long operation
progress(item.ToUpper(), id);
}
});
}
你的其他问题是“主要意见为基础”,因此不太适合堆栈溢出,但因为我在写反正,这里是我的两分钱:
•将用户提供的信息用于需要委托的功能(Action或Func)总是良好的做法吗?
始终?不是。这取决于上下文。
•是否推荐在多个函数调用中重用委托实例?
这也取决于上下文。如果您可以方便地执行此操作,或者如果您处于其他情况下需要创建大量委托实例的场景,那么您应该重新使用一个实例。
但只要没有严重的性能问题(通常不会有),你应该写在最有意义,而不是担心创建对象的方式的代码。
例如,替代你的代码,其中的代表是不重用,会是这个样子:
static void Main(string[] args)
{
var friends = new List<String>() {"joey","ross","chandler","monica","phoebe","rachel" };
var scienfelds = new List<String>() { "Jerry", "kramer", "george", "elaine" };
Action<String, String> resultProcessor = (result, id) =>
{
// process the result. let's say update the UI as and when results arrive
Console.WriteLine($"{id}: {result}");
};
var task1 = LongOperationAsync(friends, r => resultProcessor(r, "task1"));
var task2 = LongOperationAsync(scienfelds, r => resultProcessor(r, "task2"));
Task.WaitAll(task1, task2);
Console.ReadLine();
}
这样,回调定制客户端的需求代码,而不需要更改被调用者(即不需要更改为LongOperationAsync()
)。被叫方可以保持对可能有哪些类型的呼叫者不知情。
是的,你不得不创建额外的委托实例。但那又如何?你在这里做了很长时间的手术。你甚至不会在一秒钟内创建十几个,在性能问题甚至开始成为问题之前,不用介意它需要的数以万计的成本,没关系有需要解决。
您可以将进度重新定义为“Action
旁注:你应该使用Task.Run而不是Factory.Startnew:https://blog.stephencleary.com/2013/08/startnew-is-dangerous.html – GWigWam