【发布时间】:2015-02-05 22:54:40
【问题描述】:
我已经为此烦恼了很长时间,但我似乎无法找到解决此问题的方法。简而言之,我需要向我的班级展示并行编程,并且我正在制作一个演示,清楚地展示单线程和多线程之间的差异。
首先,程序截取屏幕截图并将其加载到此类中的bitmap 中。
然后它使用名为screenshot 的picturebox 加载winform。接下来它执行Form1_Load 并将屏幕截图加载到picturebox。
然后Form1_Shown 运行 for 循环,它只是根据随机化器对周围的像素进行打乱,并从左到右更新图像。
示例:http://gyazo.com/ab04583bb33de59d08407886da1c4870
这一切都有效。 我现在想让屏幕截图由第一个线程从左到中更新,第二个线程从中到右更新。
但是当我将它放在 2 个单独的线程中时,它会显示“System.Windows.Forms.dll 中发生了类型为 'System.InvalidOperationException' 的未处理异常”
该错误意味着我正在进行非法的跨线程调用。特别是在screenshot 上,也可能在mybitmap 上。
Visual Studio 通过将我链接到 "How to: Make Thread-Safe Calls to Windows Forms Controls" 来帮助我
但是我没有从这些信息中得到任何更明智的信息,这可能是因为我对 C# 术语还不是很流利。
我应该如何处理/解决这个问题?
这是发生所有事情的类(除了截屏):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ScreenOutput
{
public partial class Form1 : Form
{
PictureBox screenshot;
Bitmap myBitmap = new Bitmap(@".\screenshot.jpg");
public Form1()
{
InitializeComponent();
}
private int Xcount;
private int Ycount;
private int maxXValue = Screen.PrimaryScreen.Bounds.Width - 1;
private int maxXValueT1 = 960;
private int maxXValueT2 = 1919;
private int maxYValue = Screen.PrimaryScreen.Bounds.Height - 1;
private int maxYValueT1 = 539;
private int maxYValueT2 = 1079;
private void Form1_Load(object sender, EventArgs e)
{
screenshot.Image = myBitmap;
}
private void Form1_Shown(object sender, EventArgs e)
{
Thread startThread1 = new Thread(new ThreadStart(thread1));
Thread startThread2 = new Thread(new ThreadStart(thread2));
startThread1.Start();
startThread2.Start();
Thread.Sleep(10000); //waiting for completion
startThread1.Abort();
startThread2.Abort();
//this is how it would work without multithreading
/*Random random = new Random();
for (Xcount = 0; Xcount < maxXValue; Xcount++)
{
screenshot.Refresh();
for (Ycount = 0; Ycount < maxYValue; Ycount++)
{
int calculatedX = Xcount + random.Next(0, maxXValue);
if (calculatedX > maxXValue) calculatedX = maxXValue;
myBitmap.SetPixel(Xcount, Ycount, myBitmap.GetPixel(calculatedX, Ycount));
}
}
Thread.Sleep(2000);*/
Application.Exit();
}
public void thread1()
{
Random random = new Random();
for (Xcount = 0; Xcount < maxXValueT1; Xcount++)
{
screenshot.Refresh();
for (Ycount = 0; Ycount < maxYValueT1; Ycount++)
{
int calculatedX = Xcount + random.Next(0, maxXValueT1);
if (calculatedX > maxXValue) calculatedX = maxXValueT1;
myBitmap.SetPixel(Xcount, Ycount, myBitmap.GetPixel(calculatedX, Ycount));
}
}
}
public void thread2()
{
Random random = new Random();
for (Xcount = 0; Xcount < maxXValueT2; Xcount++)
{
screenshot.Refresh();
for (Ycount = 0; Ycount < maxYValueT2; Ycount++)
{
int calculatedX = Xcount + random.Next(0, maxXValueT2);
if (calculatedX > maxXValueT2) calculatedX = maxXValueT2;
myBitmap.SetPixel(Xcount, Ycount, myBitmap.GetPixel(calculatedX, Ycount));
}
}
}
}
}
【问题讨论】:
-
曾经考虑使用
Timer -
@MethodMan 不确定如何使用计时器解决问题?我对此还是很陌生。
-
不太可能 SO 可以为您提供比链接文章更多的帮助...关于 SO 也有许多类似的问题,但显然他们都在谈论相同的修复 - 如果您可能会得到对您更有用的答案您将问题范围缩小到您从文章中不理解的特定概念。
标签: c# .net multithreading winforms