如何停止游戏并在TPL中返回正确的价值观
本文关键字:返回 价值观 TPL 何停止 游戏 | 更新日期: 2023-09-27 18:28:13
在我的TPL应用程序中,我想通过方法PlayTTS(string text)
播放文本到语音。
public static CancellationTokenSource cTokenSource = new CancellationTokenSource();
public static CancellationToken cToken = cTokenSource.Token;
然后在消费者方法中。
async Task Consumer()
{
try
{
var executionDataflowBlockOptions = new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = 50,
CancellationToken = cToken
};
var consumerBlock = new ActionBlock<AppointmentReminder>(
remainder =>
{
if (cToken.IsCancellationRequested)
return;
Dictionary<string, string> dict = new OutboundDial(ts).RunScript(remainder, cToken);
// update UI by the returned dictionary
},
executionDataflowBlockOptions);
m_bufferBlock.LinkTo(
consumerBlock, new DataflowLinkOptions { PropagateCompletion = true });
await consumerBlock.Completion;
}
我有一个按钮事件来取消进程(WPF)。
private void Cancel_Click(object sender, RoutedEventArgs e)
{
cTokenSource.Cancel();
}
您可以看到ActionBlock
中有cToken.IsCancellationRequested
,但是在方法OutboundDial(ts).RunScript(remainder, cToken);
中停止进程并没有帮助,尽管我传入了取消令牌。
现在让我们来看看方法RunScript
。
public Dictionary<string, string> RunScript(AppointmentReminder callData, CancellationToken cToken)
{
try
{
m_ChannelResource = m_TelephonyServer.GetChannel() as SipChannel;
m_VoiceResource = m_ChannelResource.VoiceResource;
// Many logging
// Dial out
MakeTest(callData, cToken);
}
catch
{throw;}
finally
{
// destroy m_ChannelResource and m_VoiceResource
}
return dict;
}
关键是方法MakeTest
,里面有PlayTTS
;
public void MakeTest(AppointmentReminder callData, CancellationToken cToken)
{
try
{
if (!cToken.IsCancellationRequested)
{
m_VoiceResource.PlayTTS(callData.Text);
}
else
{
cToken.ThrowIfCancellationRequested();
m_VoiceResource.Stop(); // Stops any current activity on m_VoiceResource.
dict["ConnectedTime"] = " no connection";
dict["DialingResult"] = " cancellation";
}
当我单击取消按钮时,我当前的代码没有到达m_VoiceResource.Stop()
部分。所以我的问题是当cTokenSource.Cancel();
时,如何让代码在:上运行
m_VoiceResource.Stop(); // Stops any current activity on m_VoiceResource.
dict["ConnectedTime"] = " no connection";
dict["DialingResult"] = " cancellation";
编辑:2014年10月31日下午1:10
根据Servy的评论,我使用了cToken.Register(() => m_VoiceResource.Stop());
我在OneDrive上创建了一个类似的演示。
在检查令牌是否已取消并开始播放后,您将取消令牌。你再也回不去了,再也不会为了停止而执行那种状态。
你需要做的只是注册一个回调到代币的取消,停止玩家:
cToken.Register(() => m_VoiceResource.Stop());
只需在开始游戏后立即添加注册即可。
在微软MVP的帮助下,我终于找到了解决方案。Servy的解决方案很漂亮,但有缺陷。
cToken.Register(() => m_VoiceResource.Stop());
注册应该放在开始播放之前,而不是之后。
编辑:2014年11月10日上午8:09
一个更好的:
cToken.Register(() => m_VoiceResource.Stop());
return;