在运行新表单时获得InvalidOperationException是program.cs
本文关键字:InvalidOperationException cs program 新表单 运行 表单 | 更新日期: 2023-09-27 18:18:54
我正在制作一个twitch聊天机器人,出于某种原因,我有时会得到错误,说我正在对一个对象进行跨线程调用,但我找不到任何可能导致这种情况的东西,我试着在application.run语句周围制作一个try-catch语句,但这并不能修复它
Program.cs:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); // the error occurs here
}
Form1.cs:
#region variables
#region itunes variables
iTunesApp player = new iTunesApp();
#endregion
static Irc irc;
string nickname;
String message;
String rawMessage;
int dVolume = 100;
string fadeDir = "";
int fadeSpeed = 2;
#region banned_words
String[] bannedWords = { dont want to put these on this website :P};
#endregion
Thread Messages;
Form2 f2;
WebClient Client = new WebClient();
List<String> viewers;
#endregion
public Form1()
{
InitializeComponent();
player.OnPlayerPlayEvent += new _IiTunesEvents_OnPlayerPlayEventEventHandler(player_OnPlayerPlayingTrackChangedEvent);
irc = new Irc("irc.twitch.tv", 6667, "ZChembot", "oauth");
irc.joinRoom("zchem");
irc.send("Starting up...");
irc.sendIrc("CAP REQ :twitch.tv/membership");
Messages = new Thread(new ThreadStart(getMessages));
Messages.IsBackground = true;
Messages.Start();
fade.Enabled = true;
f2 = new Form2(this);
f2.Show();
getNames.Enabled = true;
}
public void player_OnPlayerPlayingTrackChangedEvent(object iTrack)
{
if (InvokeRequired)
{
this.Invoke(new Action<object>(player_OnPlayerPlayingTrackChangedEvent), new object[] { iTrack });
return;
}
IITTrack track = new iTunesApp().CurrentTrack;
if (String.IsNullOrEmpty(sound))
{
song.Text = "Song: " + track.Name;
StreamWriter file = new StreamWriter(@"c:'users'ben'desktop'twitch'Song.txt");
file.WriteLine(track.Name);
file.Close();
artist.Text = "Artist: " + track.Artist;
album.Text = "Album: " + track.Album;
}
f2.enableTimer();
f2.update();
}
public void Destroy()
{
player.OnPlayerPlayEvent -= player_OnPlayerPlayingTrackChangedEvent;
Marshal.ReleaseComObject(player);
}
#region threads
private void getMessages()
{
while (true)
{
message = irc.readMessage();
if (checkBox1.Checked)
{
updateChat("$NOTICE", message, Color.Purple);
}
rawMessage = message;
#region PRIVMSG
if (!String.IsNullOrEmpty(message))
{
if (message.Contains("PRIVMSG #zchem"))
{
nickname = rawMessage.Substring(1, message.IndexOf("!") - 1);
int start = message.IndexOf("#zchem") + 8;
String str = message.Substring(start);
message = str;
updateChat(nickname, message, Color.Black);
}
#endregion
#region notices
//successful connection
if (message.StartsWith(":tmi.twitch.tv 001 zchembot :Welcome, GLHF!"))
{
updateChat("$NOTICE", "successfully connected to the chat", Color.Green);
}
//the server pings the bot
if (message.StartsWith("PING tmi.twitch.tv"))
{
updateChat("$NOTICE", "Recieved a ping from the server", Color.Blue);
irc.sendIrc("PONG");
}
#endregion
#region play
if (message.StartsWith("!play"))
player.Play();
#endregion
#region volume up
if (message.StartsWith("!volume up"))
{
if (IsDigitsOnly(message.Substring(message.IndexOf(" ") + 1, message.Length)))
{
player.SoundVolume += int.Parse(message.Substring(message.IndexOf(" ") + 1, message.Length));
irc.send("The music volume has been changed to " + player.SoundVolume + "%");
}
}
#endregion
#region volume down
if (message.StartsWith("!volume down"))
{
if (IsDigitsOnly(message.Substring(message.IndexOf(" ", 10) + 1, message.Length)))
{
player.SoundVolume -= int.Parse(message.Substring(message.IndexOf(" ") + 1, message.Length));
irc.send("The music volume has been changed to " + player.SoundVolume + "%");
}
}
#endregion
#region vurrent volume
if (message.StartsWith("!current volume"))
{
irc.send("The current music volume is at " + player.SoundVolume + "%");
}
#endregion
#region join
if (rawMessage.EndsWith("JOIN #zchem"))
{
//detects when users join the channel
nickname = rawMessage.Substring(1, message.IndexOf("!") - 1);
irc.send("Hello, " + nickname + "!");
}
#endregion
#region part
if (rawMessage.EndsWith("PART #zchem"))
{
nickname = rawMessage.Substring(1, message.IndexOf("!") - 1);
irc.send(nickname + "has left the chat");
MessageBox.Show(nickname + "has left the chat");
}
#endregion
}
Thread.Sleep(100);
}
}
public void fade_Tick(object sender, EventArgs e)
{
if (this.Visible)
{
if (fadeDir.Equals("up"))
{
player.Play();
if (player.SoundVolume + fadeSpeed > dVolume)
player.SoundVolume = dVolume;
else
player.SoundVolume += fadeSpeed;
}
else if (fadeDir.Equals("down"))
{
if (player.SoundVolume - fadeSpeed < 0)
player.SoundVolume = 0;
else
player.SoundVolume -= fadeSpeed;
}
else if (player.SoundVolume == dVolume || player.SoundVolume == 0)
fadeDir = "";
if (player.SoundVolume == 0)
player.Pause();
}
}
#endregion
#region itunes events
private void playpause_Click(object sender, EventArgs e)
{
if (playpause.Text.Equals("❚❚"))
{
fadeDir = "down";
playpause.Text = "►";
}
else
{
fadeDir = "up";
playpause.Text = "❚❚";
}
}
private void nextSong_Click(object sender, EventArgs e)
{
player.NextTrack();
}
private void lastSong_Click(object sender, EventArgs e)
{
player.PreviousTrack();
}
private void showArt_CheckedChanged(object sender, EventArgs e)
{
if (showArt.Checked)
{
f2.Show();
}
else
{
f2.Hide();
}
}
private void soundDelay_TextChanged(object sender, EventArgs e)
{
if (!IsDigitsOnly(soundDelay.Text))
{
soundDelay.Text = "5";
}
}
#endregion
#region form events
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Destroy();
}
#endregion
bool IsDigitsOnly(string str)
{
foreach (char c in str)
{
if (c < '0' || c > '9')
return false;
}
return true;
}
public void updateChat(string nickname, string message, Color color)
{
String text;
String time = DateTime.Now.ToShortTimeString();
time = time.Substring(0, time.Length - 3);
if (InvokeRequired)
{
this.Invoke(new Action<string, string, Color>(updateChat), new object[] { nickname, message, color });
return;
}
if (nickname.Equals("$NOTICE"))
nickname = "";
else
nickname += ": ";
text = ("[" + DateTime.Now.Hour + ":" + DateTime.Now.Minute + "] " + nickname + message + "'n");
chat.SelectionStart = chat.TextLength;
chat.SelectionLength = 0;
chat.SelectionColor = color;
chat.AppendText(text);
}
}
Irc.cs:
private string username;
public TcpClient tcpClient;
private StreamReader inputStream;
private StreamWriter outputStream;
public Irc(string ip, int port, string username, string password)
{
this.username = username;
tcpClient = new TcpClient(ip, port);
inputStream = new StreamReader(tcpClient.GetStream());
outputStream = new StreamWriter(tcpClient.GetStream());
outputStream.WriteLine("PASS " + password);
outputStream.WriteLine("NICK " + username);
outputStream.WriteLine("USER " + username + " 8 * :" + username);
outputStream.Flush();
}
public void joinRoom(string channel)
{
outputStream.WriteLine("JOIN #" + channel);
outputStream.Flush();
}
public void sendIrc(string message)
{
outputStream.WriteLine(message);
outputStream.Flush();
}
public void send(string message)
{
//sendIrc(":" + username + "!" + username + "@" + ".tmi.twitch.tv PRIVMSG #zchem :" + message);
}
public string readMessage()
{
string message = inputStream.ReadLine();
Console.WriteLine(message);
return message;
}
}
}
Form2.cs:
Form1 f1;
public Form2(Form1 f1)
{
InitializeComponent();
this.f1 = f1;
timer1.Enabled = true;
}
public void update()
{
IITTrack track = player.CurrentTrack;
IITArtworkCollection Art1 = track.Artwork;
IITArtwork Art2 = Art1[1];
Art2.SaveArtworkToFile(@"c:'users'ben'desktop'twitch'Album.png");
Stream s = File.Open(@"c:'users'ben'desktop'twitch'Album.png", FileMode.Open);
Image temp = Image.FromStream(s);
s.Close();
this.BackgroundImage = resize(temp);
if (!f1.Visible)
{
System.Environment.Exit(1);
}
}
static public Bitmap Copy(Bitmap srcBitmap, Rectangle section)
{
// Create the new bitmap and associated graphics object
Bitmap bmp = new Bitmap(section.Width, section.Height);
Graphics g = Graphics.FromImage(bmp);
// Draw the specified section of the source bitmap to the new one
g.DrawImage(srcBitmap, 0, 0, section, GraphicsUnit.Pixel);
// Clean up
g.Dispose();
// Return the bitmap
return bmp;
}
public static IEnumerable<Color> GetPixels(Bitmap bitmap)
{
for (int x = 0; x < bitmap.Width; x++)
{
for (int y = 0; y < bitmap.Height; y++)
{
Color pixel = bitmap.GetPixel(x, y);
yield return pixel;
}
}
}
#region enable click-through
public enum GWL
{
ExStyle = -20
}
public enum WS_EX
{
Transparent = 0x20,
Layered = 0x80000
}
public enum LWA
{
ColorKey = 0x1,
Alpha = 0x2
}
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
public static extern int GetWindowLong(IntPtr hWnd, GWL nIndex);
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
public static extern int SetWindowLong(IntPtr hWnd, GWL nIndex, int dwNewLong);
[DllImport("user32.dll", EntryPoint = "SetLayeredWindowAttributes")]
public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, int crKey, byte alpha, LWA dwFlags);
protected void enable()
{
int wl = GetWindowLong(this.Handle, GWL.ExStyle);
wl = wl | 0x80000 | 0x20;
SetWindowLong(this.Handle, GWL.ExStyle, wl);
SetLayeredWindowAttributes(this.Handle, 0, 128, LWA.Alpha);
}
protected void disable()
{
SetWindowLong(this.Handle, GWL.ExStyle, 0);
SetLayeredWindowAttributes(this.Handle, 0, 128, LWA.Alpha);
}
#endregion
#region image stuph
public Size GenerateImageDimensions(int currW, int currH, int destW, int destH)
{
//double to hold the final multiplier to use when scaling the image
double multiplier = 0;
//string for holding layout
string layout;
//determine if it's Portrait or Landscape
if (currH > currW) layout = "portrait";
else layout = "landscape";
switch (layout.ToLower())
{
case "portrait":
//calculate multiplier on heights
if (destH > destW)
{
multiplier = (double)destW / (double)currW;
}
else
{
multiplier = (double)destH / (double)currH;
}
break;
case "landscape":
//calculate multiplier on widths
if (destH > destW)
{
multiplier = (double)destW / (double)currW;
}
else
{
multiplier = (double)destH / (double)currH;
}
break;
}
//return the new image dimensions
return new Size((int)(currW * multiplier), (int)(currH * multiplier));
}
private Image resize(Image img)
{
try
{
//calculate the size of the image
Size imgSize = GenerateImageDimensions(img.Width, img.Height, this.Width, this.Height);
//create a new Bitmap with the proper dimensions
Bitmap finalImg = new Bitmap(img, imgSize.Width, imgSize.Height);
//create a new Graphics object from the image
Graphics gfx = Graphics.FromImage(img);
//clean up the image (take care of any image loss from resizing)
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
//set the new image
return finalImg;
}
catch (System.Exception e)
{
MessageBox.Show(e.Message);
return null;
}
}
#endregion
private void timer1_Tick(object sender, EventArgs e)
{
this.Location = new Point(1920 - this.Width, 1080 - this.Height - 40);
if (Cursor.Position.X >= this.Location.X && Cursor.Position.X <= this.Location.X + this.Width && Cursor.Position.Y >= this.Location.Y && Cursor.Position.Y <= this.Location.Y + this.Height)
{
enable();
}
else
{
disable();
}
}
private void timer2_Tick(object sender, EventArgs e)
{
IITTrack track = player.CurrentTrack;
double max = track.Duration;
double val = player.PlayerPosition;
double prog = (int)(val/max * 100);
progressBar1.Value = (int)prog;
}
public void enableTimer()
{
timer2.Enabled = true;
}
}
正如调试器所说,您正在进行跨线程调用。
接口只能从主线程更新,而你正在从次线程更新。
在
上启动一个新线程Messages = new Thread(new ThreadStart(getMessages));
在getMessages函数中,你正在更新你的表单,所以这是跨线程调用。
如果你调用你的调用updateChat和MessageBox'es,我认为你会有足够的,如果没有,然后修改如果getMessages内部的一些其他函数调用也更新接口。
欢呼。
在创建线程的窗体的构造函数中试试
Form1.CheckForIllegalCrossThreadCalls = false;
注意:这是危险的