매우 긴 Python 스크립트를 비동기 적으로 실행하여 전체 응용 프로그램을 차단하지 못하도록하고 싶습니다.하지만 실행중인 동안 스트림 출력을 텍스트 상자에 쓰길 원합니다. . 나는 첫 번째 부분을 알아낼 수 있었지만 두 번째 부분은 찾아 낼 수 없었다. 현재 텍스트 상자는 스크립트가 완료된 후에 만 업데이트됩니다.IronPython 비동기 실행시 텍스트 상자에 쓰는 중
MainPage.xaml.cs를 :
...
BoxStream bs = null;
public MainPage()
{
InitializeComponent();
bs = new BoxStream(OutBox);
...
}
...
private bool slice()
{
try
{
var ipy = Python.CreateEngine();
var iscp = ipy.CreateScope();
iscp.SetVariable("rootP", Directory.GetCurrentDirectory());
ipy.ExecuteFile("Pathsetter.py", iscp);
var ipath = ipy.GetSysModule().GetVariable("path");
ScriptEngine m_engine = Python.CreateEngine();
ScriptScope m_scope = m_engine.CreateScope();
m_engine.GetSysModule().SetVariable("path", ipath);
m_engine.Runtime.IO.SetOutput(bs, Encoding.UTF8);
m_engine.Runtime.IO.SetErrorOutput(bs, Encoding.UTF8);
/*string dir = Directory.GetCurrentDirectory();
string ndir = dir.Replace(@"\", @"\\");*/
m_engine.ExecuteFile(Directory.GetCurrentDirectory() + "\\Skeinforge\\skeinforge_application\\skeinforge_utilities\\skeinforge_craft.py", m_scope);
string stl_path = Directory.GetCurrentDirectory() + "\\test.stl";
object func = m_scope.GetVariable("makeGcode");
object result = m_engine.Operations.Invoke(func, stl_path);
Debug.WriteLine(result);
}
catch (Exception ex)
{
Debug.WriteLine("Py error: " + ex.Message);
return false;
}
return true;
}
...
private void Slice_Button_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(
delegate(object o, DoWorkEventArgs args)
{
BackgroundWorker b = o as BackgroundWorker;
slice();
});
}
...
BoxStream.cs :이 아마 오히려 간단하다 생각
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using System.Windows.Controls;
namespace SkeinforgeWP8
{
class BoxStream : Stream
{
TextBox _OutBox = null;
public BoxStream(TextBox tBox)
{
Debug.WriteLine("Writing stream to box");
_OutBox = tBox;
_OutBox.Text = "";
}
public override void WriteByte(byte value)
{
base.WriteByte(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
_OutBox.Text += Encoding.UTF8.GetString(buffer, offset, count);
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void Flush()
{
return;
}
public override long Position
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override long Length
{
get { throw new NotImplementedException(); }
}
public override bool CanWrite
{
get { return true; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanRead
{
get { return false; }
}
}
}
하지만 검색을 많이 후, 여기에 내 코드의 중요한 부분입니다 내가 찾을 수있는 모든 정보는 위와 같이 BackgroundWorker를 사용한다는 정보였습니다. 내 텍스트 상자가 실시간 업데이트를받지 못하기 때문에 작동하지 않습니다.
당신이 http://stackoverflow.com에 언급 된 ProgessChanged 이벤트를 사용하여 시도 되세요/questions/2097284/update-ui-multiple-worker-threads-net? –