我有一個線程代碼,我想顯示待處理時間以完成處理。按鈕1調用 函數「Function1()」,該函數用於在while循環中控制1024字節的塊中讀取文件,直到文件的結尾 。在「While循環」中有一個「foreach循環」,其中稱爲「Function2()」。我開始 定時器在「while循環」的開始,並在「while循環」結束時停止它。之後,我嘗試 計算aprox等待時間,首先知道將由「while循環」處理的迭代次數。 然後我保存「第一次迭代的經過時間」(可以說T1),然後將其乘以迭代次數。計算待處理時間以完成處理線程代碼C#
這將是
PendingTime = T1*Iterations.
那我
PendingTime = PendingTime - Ti, where Ti is the ElapsedTime of the ith iteration.
的問題是,當我嘗試用實際的代碼,T1 *迭代multiplation給我402S,實際上 的處理需要12S。
也許一些專家可以看到我做錯了什麼。提前致謝。
的代碼看起來是這樣的:
async void button1_Click(object sender, EventArgs e)
{
//Some code
await Task.Run(() => Function1(inputfile, cts.Token), cts.Token);
//Some code
}
public void Function2()
{
//Some code
}
public void Function1(string inputfile, CancellationToken token)
{
int buffer = 1024;
int IterationCounter = 0;
decimal Iterations = 1;
int PendingTime = 0;
using (BinaryReader reader = new BinaryReader(File.Open(inputfile, FileMode.Open)))
{
FileLength = (int)reader.BaseStream.Length;
Iterations = (int)FileLength/buffer;
while (chunk.Length > 0)
{
Stopwatch sw1 = Stopwatch.StartNew(); //Start time counter
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//some code
chunk = reader.ReadBytes(buffer);
foreach (byte data in chunk)
{
//Some code
Function2(); //Call to Function2
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Checking if it is the first iteration to save the pending time
//Pending time would be the elapsed time for the first iteration
//multiplied by the number of iterations (FileLength/1024).
sw1.Stop(); //Stop time counter
if (IterationCounter == 1)
{
PendingTime = (int)((decimal)Math.Round(sw1.Elapsed.TotalMilliseconds/1000, 4)*Iterations);
}
//Show in TexBox1 the pending time
TextBox1.Invoke((MethodInvoker)delegate
{
PendingTime = PendingTime - (int)Math.Round(sw1.Elapsed.TotalMilliseconds/1000, 4);
TextBox1.Text = PendingTime + " s";
});
}
}
}
更新:
我基於彼得Duniho的例如下面的代碼測試。
它可以用任何文件(即txt文件)進行測試。我用5MB的txt文件進行了測試,執行時間爲3秒,但待處理時間在TextBox1中始終顯示爲零。我錯在哪裏?
注:我改變了這一點:
double timePerIteration = sw1.Elapsed/++IterationCounter;
這個
double timePerIteration = sw1.ElapsedMilliseconds/1000/ ++IterationCounter;
自從我得到的錯誤:
Operator '/' cannot be applied to operands of type 'System.TimeSpan' and 'int' (CS0019)
代碼至今。感謝幫助。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TestTimer
{
public partial class MainForm : Form
{
CancellationTokenSource cts = new CancellationTokenSource();
string filename = "";
long FileLength;
FileInfo fInfo;
Stopwatch sw1 = new Stopwatch();
public MainForm()
{
InitializeComponent();
}
void BtnSelectFileClick(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Select file";
DialogResult dr = ofd.ShowDialog();
if (dr == DialogResult.OK)
{
filename = ofd.FileName;
fInfo = new FileInfo(filename);
}
else
{
MessageBox.Show("File not found");
return;
}
}
async void BtnRunProcessClick(object sender, System.EventArgs e)
{
cts = new CancellationTokenSource();
await Task.Run(() => Function1(filename, cts.Token), cts.Token);
}
public void Function1(string inputfile, CancellationToken token)
{
int buffer = 1024;
int IterationCounter = 0;
int Iterations = 0;
double pendingTime = 0;
using (BinaryReader reader = new BinaryReader(File.Open(inputfile, FileMode.Open)))
{
FileLength = (int)reader.BaseStream.Length;
Iterations = (int)FileLength/buffer;
byte[] chunk;
sw1 = Stopwatch.StartNew(); //Start time counter
while (true)
{
chunk = reader.ReadBytes(buffer);
if (chunk.Length == 0) {break;}
foreach (byte data in chunk)
{
Thread.Sleep(90/100);
}
// pendingTime is the current average time-per-iteration,
// times the number of iterations left
double timePerIteration = sw1.ElapsedMilliseconds/1000/ ++IterationCounter;
pendingTime = timePerIteration * (Iterations - IterationCounter);
TextBox1.Invoke((MethodInvoker)delegate
{
// Let string.Format() take care of rounding for you
TextBox1.Text = string.Format("{0:0} s", pendingTime/1000);
});
}
MessageBox.Show("Execution time: " + string.Format("{0:0} s", sw1.ElapsedMilliseconds/1000));
}
}
}
}
沒有什麼能夠保證每次迭代都會花費相同的時間,所以我建議你根據「到目前爲止所花費的時間/到目前爲止的迭代次數」對它進行平均,然後用它來計算剩餘的估計時間。 – Chris
感謝克里斯的建議。我會盡力做到這一點。事情是,這將是一個固定值編碼,如果我嘗試在一臺速度較慢或速度較快的計算機上,時間會有所不同。 – Sarmeu
它不會被修復,它將基於迄今爲止的手術時間。 – Chris