我在Windows服务中有一个while循环,运行x次,并在从某个文件读取后启动x电话。现在,如果我想创建一个用户界面,它提供了一个停止电话呼叫的选项,即在完成之前打破while循环。我该怎么做?
假设我有一个功能。
DialCalls(x)
{
for(int i= 0 ; i<x ; i++)
{
// Initiate call
}
}
我可以在不同的线程中同时运行2,3个DialCalls函数,因为我在应用程序中也进行了线程处理。所以基本上什么是打破网页循环的最佳方式。
答案 0 :(得分:6)
使用task取消(.net 4中的新内容):
[Fact]
public void StartAndCancel()
{
var cancellationTokenSource = new CancellationTokenSource();
var token = cancellationTokenSource.Token;
var tasks = Enumerable.Repeat(0, 2)
.Select(i => Task.Run(() => Dial(token), token))
.ToArray(); // start dialing on two threads
Thread.Sleep(200); // give the tasks time to start
cancellationTokenSource.Cancel();
Assert.Throws<AggregateException>(() => Task.WaitAll(tasks));
Assert.True(tasks.All(t => t.Status == TaskStatus.Canceled));
}
public void Dial(CancellationToken token)
{
while (true)
{
token.ThrowIfCancellationRequested();
Console.WriteLine("Called from thread {0}", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(50);
}
}
http://blogs.msdn.com/b/csharpfaq/archive/2010/07/19/parallel-programming-task-cancellation.aspx 任务吞下异常所以有一些清理,可能是IDisposable? About task exceptions
答案 1 :(得分:4)
您可以在循环中编写if语句,以轮询外部事件的状态。
例如,你可以有一个标志:
bool break_out = false;
在外部事件中,将break_out标志设置为true:
break_out = true;
现在在你的循环中,你可以拥有:
DialCalls(x)
{
for(int i= 0 ; i<x ; i++)
{
// Initiate call
if (break_out) {
break;
}
}
}
答案 2 :(得分:3)
创建支持取消的活动:
public event EventHandler<CancelEventArgs> Call;
如果订户存在并取消订阅,请不要致电:
while (true)
{
var e = new System.ComponentModel.CancelEventArgs();
if (Call != null)
{
Call(this, e);
}
if (!e.Cancel)
{
// Initiate call
}
else
{
break;
}
}
答案 3 :(得分:1)
while (!_shouldStop) { /* work in progress */ }
并且在Stop()
方法中,应该在同一个worker类中,bool变量必须设置为true。
此外,如果有任何服务员(如AutoResetEvent
),则必须为.Set();
。
答案 4 :(得分:0)
通过使用变量告诉何时中断。
private bool _cancel;
void DialCalls(...)
{
for (int i=0; i<x; i++)
{
...
if (_cancel) break;
....
}
}
private void SomeEventHandler(object sender, EventArgs e)
{
_cancel = true;
}
或
for (int i=0; i<x && !_cancel; i++)
答案 5 :(得分:0)
有一个易变的全局变量
public static volatile bool stop;
stop=False;
DialCalls(x)
{
for(int i= 0 ; i<x && !stop ; i++)
{
// Initiate call
}
}
On Button Click => stop =True;
答案 6 :(得分:0)
在服务上实现一个端点,该端点接受切换全局/静态布尔(或其他某些)变量的消息,并使DialCalls
内的循环在每次迭代开始时检查所述变量。它不会中断当前正在进行的任何电话,但我打赌你不希望服务在通话过程中挂断,只是不要转到下一个。这也会中断所有线程;只需确保变量本身是线程安全的(例如,使用volatile
关键字)。