Короткая версия:передачи данных между нитями переменного приложения # WinForms
Мне нужно передать сложные данные взад и вперед между нитями, 1 нить будучи WinForm, другой поток, вызывая сервис онлайн-переводчик и изменяющийся все данные используется Winform.
Long Version:
Передача больших объемов данных в сервис онлайн-переводчик замерзал мой передний конец для минут за один раз, так что я пытаюсь переместить эту логику в нить. Winform широко использует данные, которые онлайн-служба должна обрабатывать и возвращать с помощью новой информации.
Я использую этот код, чтобы начать тему:
threadWork tw = new threadWork(); //obj to hold data for thread
tw.settings = frmMain.projectSettings;
tw.CompletedEvent += tw_CompletedEvent; // callback event, returns data
ThreadPool.QueueUserWorkItem(doWork,tw); // kick off thread
принимающего код обратного вызова:
void tw_CompletedEvent(projectFormat settings)
{
frmMain.projectSettings = settings;
NotifyLoadTransationKeys(frmMain.projectSettings.translationKeys,frmMain.projectSettings.translatedLanguages);
}
, которые в основном создали эту ошибку:
Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on. [on frmMain]
так я нашел this предлагая альтернативное использование [STAThread] [sta = single thread apartment] ins язь Program.cs (по умолчанию точка C# WinForm запись)
using System.Threading;
Thread t = new Thread(new ThreadStart(StartNewStaThread));
// Make sure to set the apartment state BEFORE starting the thread.
t.ApartmentState = ApartmentState.STA;
t.Start();
private void StartNewStaThread() {
Application.Run(new Form1());
}
Все в моей C# приложение запускается в 'Program.cs', поэтому я попытался выше предложение следующим образом:
static class Program
{
public static translationUtil TranslationUtil; //location of time intensive webservice
public static projectFormat projectSettings; //data that needs sharing
static void Main() // prog entry point
{
ProgramCode pc = new ProgramCode();
pc.Main();
}
}
class ProgramCode
{
public void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Thread t = new Thread(new ThreadStart(StartNewStaThread));
t.ApartmentState = ApartmentState.STA;
t.Start();
}
private void StartNewStaThread()
{
Application.Run(new Main());
}
}
в коде выше Я попытался переместить общие ресурсы в «Program.cs», а затем создал новый класс и поток для хранения моей winform, но это все равно дает мне проблемы с перекрестными потоками (такая же ошибка, как раньше)! Кто-нибудь получил предложения относительно использования потоков и совместного использования данных в моей ситуации?
Update: @HenkHolterman ответил на мой вопрос лучше до сих пор, но я пришел через этот код много раз после исследования ответа он дал мне (с помощью «вызова»)
if (control.InvokeRequired) {
control.Invoke(new ControlStringConsumer(SetText), new object[]{control, text}); // invoking itself
} else {
control.Text=text; // the "functional part", executing only on the main thread
}
Следуйте на вопрос. .. Вышеприведенное выше выражение «if» просто устанавливает текст без вызова (на одной из ветвей «if», следует ли мне следовать этому шаблону, что это такое?
Ошибка не имеет ничего общего с моделью квартиры. Речь идет о простой кросс-резьбе. –
см. Использование InvokeRequired для поточного безопасного вызова http://msdn.microsoft.com/en-us/library/ms171728(v=vs.85).aspx или http://social.msdn.microsoft.com/Forums/vstudio/en-US/296f8e39-fa62-4540-942a-26a53da0896a/threading-invokerequired? forum = csharpgeneral – Jade