C# 如何在以下场景中使用线程或任务模式
我有两种方法在像这样的主要方法中使用C# 如何在以下场景中使用线程或任务模式,c#,multithreading,C#,Multithreading,我有两种方法在像这样的主要方法中使用 public bool isBadMethod() { bool isBad = Method1(); if(isBad) return true; else return Method2(); } bool Method1() { ..... return true or false } bool Method2() { ..... return true or false } 如果Method1或Metho
public bool isBadMethod()
{
bool isBad = Method1();
if(isBad) return true;
else return Method2();
}
bool Method1() { ..... return true or false }
bool Method2() { ..... return true or false }
如果Method1或Method2中的任何一个返回true,则无需检查其他方法,我们可以将MainMethod返回为true。但若第一个方法返回false,那个么需要检查第二个方法,最后返回第二个方法返回的内容。这里的方法1和方法2都是耗时的方法。我可以在这些方法上使用异步编程吗。帮助如何做。(我正在使用.net 4.0)您可以利用表达式的短路:
bool val = Method1() || Method2();
如果Method1
返回true
,那么第二个方法就不麻烦了
显然,如果方法调用很昂贵,那么继续执行任务路由,因为这不是并行执行。我只是把这个贴出来,以防它是XY问题。
使用任务,这可能是您想要的。它将运行这两个方法,然后只使用一个表达式来获取正确的结果。在本例中,它会等待整整3秒钟来获取
Method2
的结果。这也会导致取消。我不确定使用的类型是否是最佳实践,因为我的经验是不完整的,但它在我的沙箱中完成了工作:
internal class Program
{
private static void Main(string[] args)
{
var cm2 = new CancellationTokenSource();
var m1 = Task.Factory.StartNew(() => Method1());
var m2 = Task.Factory.StartNew(() => Method2(cm2.Token), cm2.Token);
var val = m1.Result || m2.Result;
cm2.Cancel();
Console.WriteLine(val);
Console.ReadLine();
}
private static bool Method1()
{
Thread.Sleep(1000);
Console.WriteLine(1);
return true;
}
private static bool Method2(CancellationToken token)
{
Thread.Sleep(3000);
if (token.IsCancellationRequested)
return false;
Console.WriteLine(2);
return true;
}
}
正如Matthew Watson在评论中指出的那样,
Method2
需要使用取消令牌才能真正“取消”。在我的示例中,它只是停止打印数字并提前返回。使用任务,您的逻辑可以如下执行:
System.Threading.Tasks.Task.Factory
.StartNew<bool>(
() => { return Method1(); })
.ContinueWith<bool>(prev =>
{
if (!prev.Result)
return Method2();
else
return true;
})
.ContinueWith(prev =>
{
// do something with prev.Result
})
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
internal class Program
{
private void run()
{
Stopwatch sw = Stopwatch.StartNew();
bool result = test();
Console.WriteLine("Returned " + result + " after " + sw.Elapsed);
}
private bool test()
{
var method1 = Task.Run(new Func<bool>(Method1));
var method2 = Task.Run(new Func<bool>(Method2));
return method1.Result || method2.Result;
}
public bool Method1()
{
Console.WriteLine("Starting Method1()");
Thread.Sleep(2000);
Console.WriteLine("Returning from Method1()");
return true;
}
public bool Method2()
{
Console.WriteLine("Starting Method2()");
Thread.Sleep(3000);
Console.WriteLine("Returning true from Method2()");
return true;
}
private static void Main()
{
new Program().run();
}
}
}
System.Threading.Tasks.Task.Factory
.StartNew(
()=>{return Method1();})
.ContinueWith(上一个=>
{
如果(!上一个结果)
返回方法2();
其他的
返回true;
})
.ContinueWith(上一个=>
{
//对上一个结果做点什么
})
请注意,您可以在第二个任务中执行第三个任务的逻辑,甚至可以在一个任务中执行所有任务,这取决于您的需求。例如,您可能需要将第三个任务与UI同步。如果您不关心Method1()返回后Method2()是否继续运行,那么执行以下操作并不困难:
System.Threading.Tasks.Task.Factory
.StartNew<bool>(
() => { return Method1(); })
.ContinueWith<bool>(prev =>
{
if (!prev.Result)
return Method2();
else
return true;
})
.ContinueWith(prev =>
{
// do something with prev.Result
})
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
internal class Program
{
private void run()
{
Stopwatch sw = Stopwatch.StartNew();
bool result = test();
Console.WriteLine("Returned " + result + " after " + sw.Elapsed);
}
private bool test()
{
var method1 = Task.Run(new Func<bool>(Method1));
var method2 = Task.Run(new Func<bool>(Method2));
return method1.Result || method2.Result;
}
public bool Method1()
{
Console.WriteLine("Starting Method1()");
Thread.Sleep(2000);
Console.WriteLine("Returning from Method1()");
return true;
}
public bool Method2()
{
Console.WriteLine("Starting Method2()");
Thread.Sleep(3000);
Console.WriteLine("Returning true from Method2()");
return true;
}
private static void Main()
{
new Program().run();
}
}
}
使用系统;
使用系统诊断;
使用系统线程;
使用System.Threading.Tasks;
名称空间演示
{
内部课程计划
{
私家车
{
秒表sw=Stopwatch.StartNew();
bool结果=测试();
Console.WriteLine(“在“+sw.passed”之后返回“+result+”);
}
私人布尔测试()
{
var method1=Task.Run(newfunc(method1));
var method2=Task.Run(newfunc(method2));
返回方法1.结果| |方法2.结果;
}
公共布尔方法1()
{
WriteLine(“启动方法1()”);
《睡眠》(2000年);
WriteLine(“从Method1()返回”);
返回true;
}
公共布尔方法2()
{
WriteLine(“启动方法2()”);
睡眠(3000);
WriteLine(“从Method2()返回true”);
返回true;
}
私有静态void Main()
{
新程序().run();
}
}
}
Method1()需要2秒钟才能完成。
Method1()需要3秒钟才能完成
在Method1()设置为返回true的情况下运行时,总时间约为2秒,这是Method1()的运行时间
如果编辑Method1()使其返回false,则总时间约为3秒,即Method2()的运行时间
因此,您可以看到它并没有按顺序运行这两个任务。这种做法是一种“投机执行”
但是,如果Method1()返回true时必须取消Method2(),则会变得更复杂。理论上,您可以在单独的任务中开始这两个任务。然后,如果Method1()返回true,则取消Method2();否则,等待Method2()完成。这取决于您可以取消Method2(),这与我的答案非常相似,但我键入得太慢了。:)我想指出的是,取消令牌必须在task方法中实际使用,否则它不会做任何事情似乎没有必要,它仍然是从左到右的求值。@HenkHolterman是的,我没有看到这一点,因为我设计了一个例子,使左快于右(哦,生活在一个更简单的世界里)。“换了。”马修沃森:好的,我会记下来的。