【问题标题】:How to pass a field from the Main UI as an argument for a method from different thread如何将主 UI 中的字段作为来自不同线程的方法的参数传递
【发布时间】:2015-11-19 07:04:32
【问题描述】:

我正在使用 c# 和 Wpf 编写程序。我调用在不同线程中执行计算的方法以保持应用程序响应,但是当我尝试从主线程传递一个字段作为来自不同线程的这些方法的参数时,我得到一个异常。我试过使用 Dispatcher 它没有解决我的问题。这是在不同线程中调用的方法:

        private void Compare()
    {
        //gets a hashcode using getpixel string instance and checks if image is cropped using CompareStrings method of check instance
        BitmapImage Image1 = new BitmapImage();
        BitmapImage Image2 = new BitmapImage();
        Action a = () =>
        {
            Image1.UriSource = image1.UriSource;
            Image2.UriSource = image2.UriSource;
        };
        Dispatcher.Invoke(a);
             hashcode1 = getPixel.GetHashCode(Image1);
             hashcode2 = getPixel.GetHashCode(Image2);
             bool match = check.CompareStrings(hashcode2, hashcode1);
             if (match)
             {
                 MessageBox.Show("The image is Cropped");
             }
             else
             {
                 MessageBox.Show("These are two different images");
             }


    }

下面是调用线程的代码:

        private void CompareButton_Click(object sender, RoutedEventArgs e)
    {
        Thread workerThread = new Thread(Compare);
        workerThread.Start();
    }

这是一个 GetHashCode 方法的代码,这就是我得到异常的地方:

public List<string> GetHashCode(BitmapImage bitmap)
    {//takes a bitmap and translates it into the hashcode list
        List<string> hashCode= new List<string>();

        int stride = bitmap.PixelWidth * (bitmap.Format.BitsPerPixel / 8);
        for (int i = 0; i < bitmap.PixelHeight; i++)//divides an image into rows 
        {
            string row="";
            for (int x = 0; x < bitmap.PixelWidth; x++)//iterates through each pixel in the row
            {
                byte[] pixel = new byte[bitmap.PixelHeight];//holds color values of a single pixel
                bitmap.CopyPixels(new Int32Rect(x, i, 1, 1), pixel, stride, 0);//assigns color values of a single pixel to the pixel array
                Color singlePixel = new Color();//creates new color objects and assigns the color values found in pixel array to it
                singlePixel.B = pixel[0];
                singlePixel.G = pixel[1];
                singlePixel.R = pixel[2];
                singlePixel.A = pixel[3];
                row += singlePixel.GetHashCode().ToString();//converst the color value into the hashcode and converts it to the string
            }
            hashCode.Add(row);
            UpdatePRogress();
        }

如你所见,我尝试使用 Dispatcher 方法,但没有成功

【问题讨论】:

  • 什么是异常,它在哪一行?
  • 就个人而言,我建议您创建一个您正在使用的 BitmapImages 的副本(可能是 Bitmap 对象)并在后台线程中使用它们。

标签: c# wpf multithreading


【解决方案1】:

您必须将 BackgroundThreads 用于与 UI 相关的活动。尝试像这样更改您的代码。

    private void CompareButton_Click(object sender, RoutedEventArgs e)
    {
        BackgroundWorker workerThread = new BackgroundWorker();
        workerThread.DoWork+=workerThread_DoWork;
        workerThread.RunWorkerCompleted +=workerThread_RunWorkerCompleted;
        workerThread.RunWorkerAsync();
    }

    private void workerThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        Console.WriteLine("Process completed");
    }

    private void workerThread_DoWork(object sender, DoWorkEventArgs e)
    {
        Compare();
    }

    private void Compare()
    {
        //your method
    }

【讨论】:

    【解决方案2】:

    我尝试使用 Kosala Suggested 的后台工作人员,但它仍然没有解决我的问题,然后在谷歌搜索后我发现你可以将参数传递给 RunWorkerAsync() 然后在你的 Do_Work 类中使用它,所以我所做的是将两个包含位图图像地址的字符串值传递给 RUNWorkerAsync,然后使用它们创建位图图像的新实例,然后将这两个新实例作为参数传递给我的函数。解决方案对我来说有点脏,但我找不到更好的解决方案,所以这是我的 Do_Work 方法:

     void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            List<string> strings = (List<string>)e.Argument;
            string string1 = strings[0];
            string string2 = strings[1];
            BitmapImage image1 = new BitmapImage();
            image1.BeginInit();
            image1.UriSource = new Uri(string1);
            image1.EndInit();
    
            BitmapImage image2 = new BitmapImage();
            image2.BeginInit();
            image2.UriSource = new Uri(string2);
            image2.EndInit();
            Compare(image1, image2);
        }
    

    【讨论】:

      猜你喜欢
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-23
      • 1970-01-01
      相关资源
      最近更新 更多