2016-06-04 4 views
0

여기가 내 첫 번째 질문입니다. 영어가 제 1 언어가 아니기 때문에 어떤 실수라도 용서해주십시오.다른 스레드의 UI 업데이트

Windows Phone 8.1 (XAML 및 C#) 용 응용 프로그램을 개발하려고하는데 .NET Framework 4.5.2를 사용하고 있습니다. 방금 ​​C#에서 멀티 스레딩을 공부하기 시작했습니다. 지금까지 찾은 관련 질문에 대한 모든 대답은 너무 복잡합니다.

내가 필요한 것은 텍스트 블록 컨트롤에 메시지를 표시하는 버튼 클릭에서 새 작업을 만드는 것입니다.

다음 예외가 발생합니다. 응용 프로그램이 다른 스레드에 대해 마샬링 된 인터페이스를 호출했습니다. (HRESULT 예외 : 0x8001010E (RPC_E_WRONG_THREAD)).

어떻게 해결할 수 있습니까?

미리 감사드립니다.

+2

가능한 복제를 사용할 수 있습니다 [ C#에서 다른 스레드에서 GUI를 업데이트하는 방법?] (http://stackoverflow.com/questions/661561/how-to-update-the-gu-from-another-thread-in-c) – MickyD

+0

응용 프로그램 검색. Current.Dispatcher.Invoke 당신이 메인 스레드에서 액션을 호출 할 수있는 이런 식으로, 나는 당신이 찾고있는 것 같아. gl! – natschz

답변

0

async/await 프로그래밍 모델을 사용하면 매우 쉽게이 작업을 수행 할 수 있습니다. 대신 당신이 무엇을

,이 같은 시도 : 당신이 윈도우 폰 (WinRT,하지 실버) 프로젝트 내부에있는 경우

private async void myButton_Click(object sender, RoutedEventArgs e) 
{ 
    Task t = MyMethod(); 
    await t; 
} 

private async Task MyMethod() 
{ 
    myTextBlock.Text = "Worked!"; 
} 
+0

감사합니다. 그것은 내가 필요로했던 바로 그 것이었다. 그냥 두 가지 더 질문 : 1 - 개인 비동기 작업 MyMethod() 코드에서 'await'연산자를 사용해야합니까? 2 - C#에서 멀티 스레딩 및 async/await에 대한 추가 정보를 제안 할 수 있습니까? 다시 한번 감사드립니다. – Alexandre

+1

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx http://blog.stephencleary.com/2012/02/async-and-await.html Stephen Cleary의 나머지 블로그. 제레미 리히터 (Jeremy Richter)가 C#을 통해 자신과 CLR을 조합하여 내 정보를 배웠습니다. MyMethod에서 아무 것도 기다리지 않아도됩니다.이 경우 경고를 무시해도됩니다. – bodangly

+0

@Alexandre 귀하의 영어가 제게 아주 잘 보이는 것처럼 보이지만, 귀하의 모국어가 아닌 것으로 추측했을 것입니다. – bodangly

0

디자이너 코드 :

namespace Tasks 
{ 
    partial class Form1 
    { 
     /// <summary> 
     /// Required designer variable. 
     /// </summary> 
     private System.ComponentModel.IContainer components = null; 

     /// <summary> 
     /// Clean up any resources being used. 
     /// </summary> 
     /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
     protected override void Dispose(bool disposing) 
     { 
      if (disposing && (components != null)) 
      { 
       components.Dispose(); 
      } 
      base.Dispose(disposing); 
     } 

     #region Windows Form Designer generated code 

     /// <summary> 
     /// Required method for Designer support - do not modify 
     /// the contents of this method with the code editor. 
     /// </summary> 
     private void InitializeComponent() 
     { 
      this.button1 = new System.Windows.Forms.Button(); 
      this.button2 = new System.Windows.Forms.Button(); 
      this.textBox1 = new System.Windows.Forms.TextBox(); 
      this.SuspendLayout(); 
      // 
      // button1 
      // 
      this.button1.Location = new System.Drawing.Point(41, 43); 
      this.button1.Name = "button1"; 
      this.button1.Size = new System.Drawing.Size(75, 23); 
      this.button1.TabIndex = 0; 
      this.button1.Text = "button1"; 
      this.button1.UseVisualStyleBackColor = true; 
      this.button1.Click += new System.EventHandler(this.button1_Click); 
      // 
      // button2 
      // 
      this.button2.Location = new System.Drawing.Point(131, 43); 
      this.button2.Name = "button2"; 
      this.button2.Size = new System.Drawing.Size(75, 23); 
      this.button2.TabIndex = 1; 
      this.button2.Text = "button2"; 
      this.button2.UseVisualStyleBackColor = true; 
      this.button2.Click += new System.EventHandler(this.button2_Click); 
      // 
      // textBox1 
      // 
      this.textBox1.Location = new System.Drawing.Point(41, 84); 
      this.textBox1.Name = "textBox1"; 
      this.textBox1.Size = new System.Drawing.Size(165, 20); 
      this.textBox1.TabIndex = 2; 
      // 
      // Form1 
      // 
      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
      this.ClientSize = new System.Drawing.Size(240, 151); 
      this.Controls.Add(this.textBox1); 
      this.Controls.Add(this.button2); 
      this.Controls.Add(this.button1); 
      this.Name = "Form1"; 
      this.Text = "Form1"; 
      this.ResumeLayout(false); 
      this.PerformLayout(); 

     } 

     #endregion 

     private System.Windows.Forms.Button button1; 
     private System.Windows.Forms.Button button2; 
     private System.Windows.Forms.TextBox textBox1; 
    } 
} 

이 양식 코드 :

using System; 
using System.Diagnostics; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Tasks 
{ 
    public partial class Form1 : Form 
    { 
     //Just incase you need to stop the current task 
     CancellationTokenSource cts; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button2_Click(object sender, EventArgs e) 
     { 
      //showing that the form is still working 
      MessageBox.Show(this,"This button still works :)"); 
     } 

     private async void button1_Click(object sender, EventArgs e) 
     { 
      cts = new CancellationTokenSource(); 

      await CreateTask(); 
     } 

     private async Task CreateTask() 
     { 
      //Create a progress object that can be used within the task 
      Progress<string> mProgress; //you can set this to Int for ProgressBar 
      //Set the Action to a function that will catch the progress sent within the task 
      Action<string> progressTarget = ReportProgress; 
      //Your new Progress with the included action function 
      mProgress = new Progress<string>(progressTarget); 

      //start your task 
      string result = await MyProcess(mProgress); 

      MessageBox.Show(this, result); 
     } 

     //notice the myProgress this can be used within your task to report back to UI thread. 
     private Task<string> MyProcess(IProgress<string> myProgress) 
     { 
      return Task.Run(() => 
      { 
       //here you will sen out to your UI thread whatever text you want. 
       //typically used for progress bar. 
       myProgress.Report("It Works.."); 
       //your tasks return 
       return "Yes it really does work..."; 

      }, cts.Token); 
     } 

     private void ReportProgress(string message) 
     { 
      //typically to update a progress bar or whatever 
      //this is where you Update your UI thread with text from within the Task. 
      textBox1.Text = message; 
     } 
    } 
} 

기본적으로 당신이 당신이 당신의 작업에 사용할 수있는 진행에 전달하고 무엇을하고 있는지.

+0

정말 도움이되기 위해 여기서 무엇이 일어나는지 설명해야합니다. – bodangly

+0

코드 내에 주석을 추가했습니다. 솔루션을 이해하는 데 도움이됩니다. – EJD

0

당신은 또한의

await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, new DispatchedHandler(() => 
     { 
      // your code 
     })); 
관련 문제