使用线程并行调用两个方法 - 一个在完成之前执行

时间:2014-03-10 07:54:18

标签: c# asp.net multithreading parallel-processing backgroundworker

我在C#应用程序中使用多线程来上传图像。

流程是,首先我要调整图像的大小。                 第二,我正在上传它们。

代码就像:

上传按钮单击

private void Button_Click_1(object sender, RoutedEventArgs e)
{
            ResizeImagesAtLocal();
            UploadImageToCloud();
}               


private void ResizeImagesAtLocal()
{
            var worker = new BackgroundWorker
                {
                    WorkerReportsProgress = true
                };

            worker.DoWork += worker_ResizeImages;
            worker.ProgressChanged += worker_ResizeProgressChanged;

            worker.RunWorkerAsync();
}

private void worker_ResizeProgressChanged(object sender, ProgressChangedEventArgs e)
{
   ResizeProgress.Value = e.ProgressPercentage;
}

private void worker_ResizeImages(object sender, DoWorkEventArgs e)
{
    ...
}


private void UploadImageToCloud()
{
            var worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.DoWork += worker_UploadImages;
            worker.ProgressChanged += worker_UploadProgressChanged;

            worker.RunWorkerAsync();
}

void worker_UploadProgressChanged(object sender, ProgressChangedEventArgs e)
{
    UploadProgress.Value = e.ProgressPercentage;
}

void worker_UploadImages(object sender, DoWorkEventArgs e)
{
  ...
}

问题是,ResizeImagesAtLocal尚未完成,上传图片开始执行,这导致了问题..

有没有办法确保.. ResizeImagesAtLocal完成所有工作,然后我们可以调用上传方法。

2 个答案:

答案 0 :(得分:0)

您可以使用4.0版本中的Task

你可以做(​​伪代码):

Task.Factory.StartNew(()=> {
}). ContinuewWith(...);
ContinueWith任务完成后

StartNew将被称为

答案 1 :(得分:0)

如果您对使用Microsoft的Reactive Framework感到满意,可以使用以下方法:

Func<Image, Image> resizeImage = i => { /* resize image */ };
Func<Image, System.Uri, bool> uploadImage = (i, u) => { /* upload image */ };
var uri = /* upload uri */;

var query =
    from image in images.Select((x, n) => new { x, n }).ToObservable()
    from thumbnail in Observable.Start(() => resizeImage(image.x))
    from uploaded in Observable.Start(() => uploadImage(thumbnail, uri))
    select new
    {
        image = image.x,
        index = image.n,
        thumbnail,
        uploaded,
    };

query
    .ObserveOn(SynchronizationContext.Current)
    .Subscribe(x =>
    {
        UploadProgress.Value = x.index * 100 / images.Count();
        /* do other stuff if needed on UI thread */
    });

就是这样。它全部并行处理后台线程。它将更新编组到UI线程上。 Subscribe方法返回IDispose,可用于停止后台线程。它们都可以在Click事件处理程序中编码。