异步运行同步方法

时间:2015-03-01 00:36:02

标签: c#

我正在尝试异步运行同步方法,因此我可以使用其进度更新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() { }
}

我不确定如何攻击这个。如果我不能很好地解释这个问题,请告诉我。

2 个答案:

答案 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();

对不起,如果我所说的任何内容太混乱了。