从按钮取消异步任务 [英] Cancel Async Task from a button
问题描述
我需要做的是能够取消运行异步任务是什么。
我一直在寻找,似乎无法环绕它我的头。我只是不能似乎辨别将如何落实到我的当前设置。
下面是我的code,它激发我的任务了。在哪里或如何实施取消标记任何帮助将大大AP preciated。
专用异步无效startThread()
{
//开始前做UI的东西
ProgressLabel.Text =的String.Format(0 / {0}完成奔流,index.Count());
ProgressBar.Maximum = index.Count(); 等待ExecuteProcesses(); //排序的输出线列表
outputList = outputList.OrderBy(O => o.RunNumber).ToList(); 的foreach(在outputList输出O)
{
串outStr = o.RunNumber +,+ o.Index;
的foreach(双OV在o.Values)
{
outStr + =的String.Format({0},OV);
} outputStrings.Add(outStr);
} 字符串[] = csvOut outputStrings.ToArray(); File.WriteAllLines(settings.OutputFile,csvOut);
//完成后做UI的东西。 ProgressLabel.Text = index.Count()+奔跑完成输出写入文件test.csv。
} 私人异步任务ExecuteProcesses()
{
等待Task.Factory.StartNew(()=>
{
INT mycount的= 0;
INT maxRuns = index.Count();
清单<串GT; myStrings =指数;
Parallel.ForEach(myStrings,
新ParallelOptions()
{
MaxDegreeOfParallelism = settings.ConcurrentRuns
},(S)=>
{
//这条线就是我们的目标运行计数。
INT myIndex = myStrings.IndexOf(多个)+ 1; 串newInputFile = Path.Combine(settings.ProjectPath +文件/,Path.GetFileNameWithoutExtension(settings.InputFile)+ S +.INP,。);
串newRptFile = Path.Combine(settings.ProjectPath +文件/,Path.GetFileNameWithoutExtension(settings.InputFile)+ S +的.rpt,。); 尝试
{
//负载的输入文件的内容
字符串[] = allLines File.ReadAllLines(Path.Combine(settings.ProjectPath,settings.InputFile));
字符串[] = indexSplit s.Split('。'); 这里//改变参数
诠释计数= 0;
的foreach(OptiFile的文件)
{
INT I = Int32.Parse(indexSplit [计数]);
的foreach(OptiParam oP处的oF.Parameters)
{
串线= allLines [oP.LineNum - 1];
如果(oP.DecimalPts == 0)
{
字符串SEX pression = oP.Value;
SEX pression =性爱pression.Replace(%i的,i.ToString());
EqCompiler oCompiler =新EqCompiler(SEX pression,真正的);
oCompiler.Compile();
INT iValue =(int)的oCompiler.Calculate(); allLines [oP.LineNum - 1] = line.Substring(0,oP.ColumnNum - 1)+ iValue.ToString()+ line.Substring(oP.ColumnNum + oP.Length);
}
其他
{
字符串SEX pression = oP.Value;
SEX pression =性爱pression.Replace(%i的,i.ToString());
EqCompiler oCompiler =新EqCompiler(SEX pression,真正的);
oCompiler.Compile();
双dValue = oCompiler.Calculate();
dValue = Math.Round(dValue,oP.DecimalPts); allLines [oP.LineNum - 1] = line.Substring(0,oP.ColumnNum - 1)+ dValue.ToString()+ line.Substring(oP.ColumnNum + oP.Length);
}
}
算上++;
}
//这里写新的输入文件
File.WriteAllLines(newInputFile,allLines);
}
赶上(IOException异常前)
{
MessageBox.Show(ex.ToString());
}
VAR工艺=新工艺();
process.StartInfo =新的ProcessStartInfo(swmm5.exe,newInputFile ++ newRptFile);
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
的Process.Start();
process.WaitForExit(); 输出输出=新的输出();
output.RunNumber = myIndex;
output.Index =秒;
output.Values =新的List<双>(); 的foreach(OutputValue OV在OutputValues){
output.Values.Add(oV.getValue(newRptFile));
} outputList.Add(输出); //运行后摆脱文件
File.Delete(newInputFile);
File.Delete(newRptFile); mycount的++;
ProgressBar.BeginInvoke(
新的Action(()=>
{
ProgressBar.Value = mycount的;
}
));
ProgressLabel.BeginInvoke(
新的Action(()=>
{
ProgressLabel.Text =的String.Format({0} / {1}奔流完成,mycount的,maxRuns);
}
));
});
});
}
要支持取消的最好方法是通过一个的CancellationToken
到异步
方法。然后,按钮preSS可绑取消标记
类theClass描述
{
CancellationTokenSource m_source; 无效StartThread(){
m_source =新CancellationTokenSource;
StartThread(m_source.Token);
} 私人异步无效StartThread(令牌的CancellationToken){
...
} 私人无效OnCancelClicked(对象发件人,EventArgs的发送){
m_source.Cancel();
}
}
这是不是很够,但。无论是 startThread
和 StartProcess
方法都需要进行更新,以共同取消该任务一旦的CancellationToken
注册为取消
What I need to do is be able to cancel a task that is running async.
I have been searching and cannot seem to wrap my head around it. I just cant seem to discern how it would be implemented into my current setup.
Here is my code that fires my task off. Any help on where or how to implement a cancellation token would be greatly appreciated.
private async void startThread()
{
//do ui stuff before starting
ProgressLabel.Text = String.Format("0 / {0} Runs Completed", index.Count());
ProgressBar.Maximum = index.Count();
await ExecuteProcesses();
//sort list of output lines
outputList = outputList.OrderBy(o => o.RunNumber).ToList();
foreach (Output o in outputList)
{
string outStr = o.RunNumber + "," + o.Index;
foreach (double oV in o.Values)
{
outStr += String.Format(",{0}", oV);
}
outputStrings.Add(outStr);
}
string[] csvOut = outputStrings.ToArray();
File.WriteAllLines(settings.OutputFile, csvOut);
//do ui stuff after completing.
ProgressLabel.Text = index.Count() + " runs completed. Output written to file test.csv";
}
private async Task ExecuteProcesses()
{
await Task.Factory.StartNew(() =>
{
int myCount = 0;
int maxRuns = index.Count();
List<string> myStrings = index;
Parallel.ForEach(myStrings,
new ParallelOptions()
{
MaxDegreeOfParallelism = settings.ConcurrentRuns
}, (s) =>
{
//This line gives us our run count.
int myIndex = myStrings.IndexOf(s) + 1;
string newInputFile = Path.Combine(settings.ProjectPath + "files/", Path.GetFileNameWithoutExtension(settings.InputFile) + "." + s + ".inp");
string newRptFile = Path.Combine(settings.ProjectPath + "files/", Path.GetFileNameWithoutExtension(settings.InputFile) + "." + s + ".rpt");
try
{
//load in contents of input file
string[] allLines = File.ReadAllLines(Path.Combine(settings.ProjectPath, settings.InputFile));
string[] indexSplit = s.Split('.');
//change parameters here
int count = 0;
foreach (OptiFile oF in Files)
{
int i = Int32.Parse(indexSplit[count]);
foreach (OptiParam oP in oF.Parameters)
{
string line = allLines[oP.LineNum - 1];
if (oP.DecimalPts == 0)
{
string sExpression = oP.Value;
sExpression = sExpression.Replace("%i", i.ToString());
EqCompiler oCompiler = new EqCompiler(sExpression, true);
oCompiler.Compile();
int iValue = (int)oCompiler.Calculate();
allLines[oP.LineNum - 1] = line.Substring(0, oP.ColumnNum - 1) + iValue.ToString() + line.Substring(oP.ColumnNum + oP.Length);
}
else
{
string sExpression = oP.Value;
sExpression = sExpression.Replace("%i", i.ToString());
EqCompiler oCompiler = new EqCompiler(sExpression, true);
oCompiler.Compile();
double dValue = oCompiler.Calculate();
dValue = Math.Round(dValue, oP.DecimalPts);
allLines[oP.LineNum - 1] = line.Substring(0, oP.ColumnNum - 1) + dValue.ToString() + line.Substring(oP.ColumnNum + oP.Length);
}
}
count++;
}
//write new input file here
File.WriteAllLines(newInputFile, allLines);
}
catch (IOException ex)
{
MessageBox.Show(ex.ToString());
}
var process = new Process();
process.StartInfo = new ProcessStartInfo("swmm5.exe", newInputFile + " " + newRptFile);
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
process.WaitForExit();
Output output = new Output();
output.RunNumber = myIndex;
output.Index = s;
output.Values = new List<double>();
foreach(OutputValue oV in OutputValues) {
output.Values.Add(oV.getValue(newRptFile));
}
outputList.Add(output);
//get rid of files after run
File.Delete(newInputFile);
File.Delete(newRptFile);
myCount++;
ProgressBar.BeginInvoke(
new Action(() =>
{
ProgressBar.Value = myCount;
}
));
ProgressLabel.BeginInvoke(
new Action(() =>
{
ProgressLabel.Text = String.Format("{0} / {1} Runs Completed", myCount, maxRuns);
}
));
});
});
}
The best way to support cancellation is to pass a CancellationToken
to the async
method. The button press can then be tied to cancelling the token
class TheClass
{
CancellationTokenSource m_source;
void StartThread() {
m_source = new CancellationTokenSource;
StartThread(m_source.Token);
}
private async void StartThread(CancellationToken token) {
...
}
private void OnCancelClicked(object sender, EventArgs e) {
m_source.Cancel();
}
}
This isn't quite enough though. Both the startThread
and StartProcess
methods will need to be updated to cooperatively cancel the task once the CancellationToken
registers as cancelled
这篇关于从按钮取消异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!