나는 최근에 C #을 배우고 있으며 머리를 감쌀 수없는 문제가 있습니다. C #을 처음 접했지만 내 질문은 대리자와 호출에 관한 것이므로 이것이 멍청한 경우 용서해주십시오. 나는 온라인에서 많은 튜토리얼을 읽고 이것에 대한 많은 비디오 튜토리얼을 보았지만 여전히 코드에서 동일한 오류가 발생하고 미묘한 부분을 파악하지 못하는 것 같습니다. 내가 이해했듯이 대리자는 함수에 대한 포인터이며 다른 스레드에서 해당 함수를 호출하여 텍스트 상자를 업데이트하는 데 사용할 수 있습니다. 대리자를 만드는 것을 이해합니다. 제가 옳은 일을한다고 생각하지만 위협에서 대리자를 호출 할 때 항상 크로스 스레드 작업이 유효하지 않습니다. 생성 된 스레드 이외의 스레드에서 액세스 한 'textBox1'제어 오류가 발생 합니다. 의 위에.
콜백은 설계된 함수를 호출하기 때문에 작동하는 것처럼 보이지만 이런 식으로 수행하는 요점이라고 생각한 올바른 스레드에서 수행하지 않는 것 같습니다. 경고 중단을 false로 설정하는 옵션이 있다는 것을 알고 있지만 내가 뭘 잘못하고 있는지,이 유형의 메서드를 올바르게 코딩하는 방법을 배우고 싶습니다. 나는 더 이상 튜토리얼이 내가 어디에서 잘못되었는지 이해하는 데 더 가까워지고 있는지 확실하지 않으므로 제공 할 수있는 도움, 제안 또는 답변에 감사드립니다.
내 코드는 매우 기본적이며 멀티 스레딩을위한 적절한 코딩의 가장 기본적인 개념을 이해하려고합니다. 아래는 내 코드입니다.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Media;
using System.Threading;
using System.Reflection;
namespace WindowsFormsApplication3
{
//declair delegate name(vars) CORRECT
public delegate void Textboxdelegate(Int64 MyVar);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
runme();
}
public void runme()
{
textBox1.Text = "87";
textupdate(44);
int target = 0;
Textboxdelegate TD = new Textboxdelegate(textupdate);
Number number = new Number(target, TD);
TD(11);
Thread thread1 = new Thread(new ThreadStart(number.worker));
thread1.Start();
}
public void textupdate(Int64 cntr)
{
textBox1.Text += cntr.ToString();
}
}
class Number
{
int _target;
Textboxdelegate _callbackMethod;
public Number(int target, Textboxdelegate TDD)
{
this._target = target;
this._callbackMethod = TDD;
}
public void worker()
{
Int64 counter = 0;
byte[] lifeforms = new byte[2146435071];
for (long y = 1; y <= 2146; y++)
{
for (long X = 1; X <= 1000000; X++)
{
lifeforms[X * y] = 20;
}
counter += 1;
if(_callbackMethod != null)
{
_callbackMethod(counter);
}
}
MessageBox.Show("Done!");
}
}
}
이 조잡한 예제는 원하는 작업을 수행해야합니다.
//public delegate void Textboxdelegate(Int64 MyVar);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Action<Int64> Textboxdelegate;
public void runme()
{
textBox1.Text = "87";
textupdate(44);
int target = 0;
Textboxdelegate = textupdate;
Number number = new Number(target, Textboxdelegate,this);
Textboxdelegate(11);
Thread thread1 = new Thread(new ThreadStart(number.worker));
thread1.Start();
}
public void textupdate(Int64 cntr)
{
textBox1.Text += cntr.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
runme();
}
}
class Number
{
int _target;
Action<Int64> _callbackMethod;
Form1 frm;
public Number(int target, Action<Int64> act,Form1 frm)
{
this._target = target;
this._callbackMethod = act;
this.frm = frm;
}
public void worker()
{
Int64 counter = 0;
byte[] lifeforms = new byte[214643507];
for (long y = 1; y <= 2146; y++)
{
for (long X = 1; X <= 100000; X++)
{
lifeforms[X * y] = 20;
}
counter += 1;
if (_callbackMethod != null)
{
if (frm.InvokeRequired)
{
frm.Invoke(_callbackMethod,new object[]{counter});
}
else
{
_callbackMethod(counter);
}
}
}
MessageBox.Show("Done!");
}
}
컨트롤은 스레드 친 화성을 가지므로 컨트롤을 생성 한 스레드에서만 액세스 할 수 있으며 다른 스레드에서 액세스 할 수 있습니다. 이제 Control 클래스의 Invoke 메서드 (폼의 기본 및 모든 컨트롤)를 사용하면 안전하게 액세스하십시오 (매우 요약 된 설명).
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다