我正在尝试异步运行同步方法,因此我可以使用其进度更新UI。我必须使用几个不同的数据运行相同的同步方法,但一次只能有一个此方法的实例。
这就是我尝试过的,这不完全是我的程序的样子,但我已将其简化以尽量减少混淆。
class Program
{
static int[] data = new int[10]
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
};
static void Main(string[] args)
{
Method(0);
}
static void Method(int parameter)
{
if (parameter < data.Length)
{
Worker worker = new Worker();
worker.OnProgressChange += delegate
{
// Update UI
};
worker.OnWorkComplete += delegate
{
Method(parameter++);
};
worker.DoWork();
}
}
}
class Worker
{
public event EventHandler OnProgressChange;
public event EventHandler OnWorkComplete;
public Worker() { }
public void DoWork() { }
}
我不确定如何攻击这个。如果我不能很好地解释这个问题,请告诉我。
答案 0 :(得分:0)
.NET已经为你完成了它:BackgroundWorker Class
基本上您需要做的就是更改您的Method参数以限制BackgroundWorker (object sender, DoWorkEventArgs e)
并调用RunWorkAsync
答案 1 :(得分:0)
好的,我找到了解决方案!答案不适用于我上面提到的抽象场景,但想法是一样的。
private bool flag = false;
private void CheckCompletion()
{
// Do stuff
ConvertFiles();
while (!flag)
Application.DoEvents();
// Do more stuff
}
private void ConvertFiles()
{
UpdateStatus("Converting...", true);
Task.Factory.StartNew(() =>
{
using (Engine engine = new Engine())
{
for (int i = 0; i < entries.Count; i++)
{
MediaFile inputFile = new MediaFile(entries[i].FilePath);
MediaFile outputFile = new MediaFile(entries[i].FilePath.Replace(".aac", ".mp3"));
engine.ConvertProgressEvent += (obj, args) =>
{
int value = (int)Math.Round(args.ProcessedDuration.TotalSeconds /
args.TotalDuration.TotalSeconds);
Invoke(new Action(delegate { entries[i].ProgressBarEx.Value = value; }));
};
engine.Convert(inputFile, outputFile);
}
}
flag = true;
});
}
如果需要异步运行同步方法,请使用任务并行库。如果您需要运行异步运行同步任务的多个实例,但一次只运行一个,请在该任务中放置一个for loop
,并在所有任务完成后让bool
变量告诉应用程序。它是纯粹魔法的while(!flag) Application.DoEvents();
。
对不起,如果我所说的任何内容太混乱了。